puppeteer page.select with multiple class doesn't seem to work - puppeteer

I'm new to puppeeteer I have this html https://jsitor.com/c0rM-YohL
<input type="input" class="test-element Input">
<select class="test-element Dropdown">
<option>test1</option>
<option>test2</option>
</select>
I tried with this chrome extension https://chrome.google.com/webstore/detail/puppeteer-ide/ilehdekjacappgghkgmmlbhgbnlkgoid?hl=en-US
await page.type(".test-element .Input", "new-test-app");
await page.select(".test-element .Dropdown", "option1");
but it doesn't work with
await page.goto('https://jsitor.com/c0rM-YohL', {
waitUntil: 'networkidle0',
});
await page.type(".test-element.Input", "new-test-app");
await page.select(".test-element.Dropdown", "option1");

remove the extra space from the selectors:
await page.type(".test-element.Input", "new-test-app");
await page.select(".test-element.Dropdown", "option1");
EDIT:
it's within an iframe, so you need to get iframe first:
const iframeSelector = '.iframe-container iframe';
await page.waitForSelector(iframeSelector, {
visible: true
});
const frameHandle = await page.$(iframeSelector);
const frame = await frameHandle.contentFrame();
await frame.type(".test-element.Input", "new-test-app");
let selected = await frame.select(".test-element.Dropdown", "test2");
console.log('selected', selected);

option1 is an element inside the <select> object. You need to type your text, click on the dropdown, and only then click on the relevant option.

Related

Not clicking on element after class specifically called

For some reason I'm not able to click on an element that appears on a screen with puppeteer js.
Here is the code:
const getAllElements = await page.$$('._1Nk0C');
for (let [i, link] of getAllElements.entries()) {
try {
await link.click();
await sleep.sleep(4);
await link.click('._1NHYN _3d86A Ddtb4');
} catch (e) {
console.error(e);
}
}
Here I find all elements with '._1Nk0C'
It then clicks on the element which as it enlarge in forefront. await link.click();
I then try to click the button on screen. I can confirm this is on the screen.
await link.click('._1NHYN _3d86A Ddtb4');
Nothing happens. It doesn't error out just doesn't click on element. Am I missing something?
elementHandle.click([options]) does not accept a selector as an argument. If you're trying to click on an element in the page based on its selector try:
await link.click();
await sleep.sleep(4);
await page.click(selector);

pupppeteer js element not clicking even thou it is available in console

I have the following element in html.
<a title="Download photo" href="https://example.com/photos/GXqvtQh1N9A/download?force=true" rel="nofollow" download="" target="_blank" class="_1QwHQ _1l4Hh _1CBrG _1zIyn xLon9 _1Tfeo _2L6Ut _2Xklx"><svg class="Apljk _11dQc" version="1.1" viewBox="0 0 32 32" width="32" height="32" aria-hidden="false"></a>
From the console when Chromium is open.
I can query it like so:
document.querySelector('a[title="Download photo"]');
I can create a reference to it:
var link = document.querySelector('a[title="Download photo"]');
I then can click on it like so:
link.click();
I try the same exact thing in Puppeteer.js in code. Same page.
for (const handle of getAllElements) {
try {
await handle.click();
const downloadButton = await page.$('a[title="Download photo"]');
downloadButton.click();
await sleep.sleep(2000);
} catch (e) {
console.error(e);
}
}
The initial handle.click() works and it opens me to the page I'm discussing here.
But then downloadButton.click() doesn't function.
I've also tried page.click(downloadButton).
I've also tried:
const downloadButton = await page.$('a[title="Download photo"]');
await downloadButton.click();
To ensure I'm working with the same page I visually do it while the page is on the screen.
Any ideas what's gong on?
As you mentioned it opens a layer on top each time you click on the image. Also, a[title="Download photo"] needs to be relative to the handle not page. Here is the working code:
for (const handle of getAllElements) {
await handle.click();
await handle.$eval('a[title="Download photo"]', el => el.click());
//allow download
await page._client.send('Page.setDownloadBehavior', {
behavior: 'allow',
downloadPath: './'
});
await new Promise(resolve => setTimeout(resolve, 2000));
//click on X to close the layer
await page.click('._1NHYN');
}

puppeteer.js click hyperlink with a class

async function main() {
const browser = await puppeteer.launch({ headless: false});
const page = await browser.newPage();
await page.goto(url);
console.log(await page.title());
await page.click('a.search-name');
}
<div class="search-results-content-container">
<div class="search-results-image-container">
</div>
<div class="search-results-details-container">
<h4 class="search-name">Doe, Johm</h4>
<p class="search-title">
center of art
</p>
</div>
Hi I am using puppeteer to automate some tasks and I am moving along until it is time to click a h4 link that has a class called 'search-name'. I have tried adding await page.click('a.search-name') but that does not work. I also tried await page.click('h4.search-name') but no luck either. Can someone tell me how to make it click a link with an interchangeable url. It is the reason I want to specifically click h4 with a class of search-name.
The below code is what works!
await page.waitForSelector('.search-name')
await page.click('.search-name');

fill in input empty but still have texts

I am using puppeteer to scrape a page, there is a simple form for searching on the page
I enter a search text in one input, the others are empty, however, when i click on the search, the others input are not empty, what' s wrong with it ?
await page.goto('http://www.dollmedia-btp.com/annuaire/', {waitUntil: 'domcontentloaded'});
await page.type("input#input-recherche-activite", "Maçonnerie");
await page.type("input#input-recherche-raison-sociale", "");
await page.type("input#input-recherche-ville","");
await page.type("input#input-recherche-tel", "");
I don' t know what to do, thanks for your helps
You have to clear the fields, the type method with an empty string does not remove the input's value.
Custom function:
async function clear(page, selector) {
await page.evaluate(selector => {
document.querySelector(selector).value = "";
}, selector);
}
Usage:
await clear(page,"input#input-recherche-raison-sociale");
Or without creating function:
await page.$eval('#input-recherche-raison-sociale', el => el.value = '');

how to delete the added item to the form in puppeteer

I am having issue with puppeteer.
I want to delete the added item to the form. For example, I have a form and added some fake data ("example"). I want to delete this "example", it doesn't matter whatever position it located. I just only want to delete this "example".
So, it means, puppeteer adds it and will delete in the next step.
I have tried:
// fake data
const metadatatest = {
text: 'example,
}
describe('Should be navigate through details', () => {
it('can navigate through detail', async () => {
// this adds fake data successfully
await page.waitForSelector('[data-testid="appCard"]')
await page.click('[data-testid="appCardDetails"]')
await page.waitForSelector('[data-testid="overviewSectionMetadataForm"]')
await page.click('[data-testid="overviewSectionMetadataEditButton"]')
//await page.$eval('[data-testid="metadataInput"]', el => el.value = 'example')
await page.type('[data-testid="metadataInput"]', metadatatest.text)
await page.waitForSelector('[data-testid="metadataInput"]')
await Promise.all([
page.click('[data-testid="overviewSectionMetadataEditButton"]'),
]);
// I want to delete this
})
})
I have also tried using
await page.keyboard.press('Backspace')
await page.keyboard.press('Clear')
await page.keyboard.press('Delete')
but no luck.
any help please!
So what you're asking is about clearing text from an input field, am I reading that correctly? Puppeteer doesn't have a built in method for that but I have found a workaround which will do it for you.
First, you need to click 3 times on the input field you wish to clear. This acts as a select all action for all text entered in that element:
await page.click(selector, { clickCount: 3 });
Now you can use your previous attempt to clear the text:
await page.keyboard.press('Backspace');
Update 1:
Your final code for clearing and then entering the text you want into the input field should look something like this:
await page.click('[data-testid="metadataInput"]', { clickCount: 3 });
await page.keyboard.press('Backspace');
await page.type('[data-testid="metadataInput"]', metadatatest.text);