Node js Click with puppeteer an element that has no id or name - node.js

Hi everyone I'm trying to click with puppeteer three elements that do not have an id, a name and a class; these are the checkboxes and the button that I have to click (www.omegle.com):
i tried to do it through the click with the coordinates but I can't center the elements to click:
await page.mouse.click(50, 200);
await page.waitForNavigation();
})()
So is there a way to click on an element without knowing its id, class or name?

// open modal by clicking "Text" button
const btnText = await page.waitForSelector('#chattypetextcell img')
await btnText.click()
// click both checkbox labels when modal opens
const selectorCheckboxLabels ='div div p label'
await page.waitForSelector(selectorCheckboxLabels)
const labels = await page.$$(selectorCheckboxLabels)
await labels[0].click()
await labels[1].click()

Related

Puppeteer: how to foreach every button class and click if specific class name found

How to foreach every button class and click if specific class name found
<button class="b-deliverytime--slot b-deliverytime--slot-unavailable" aria-label="Not Available Today" title="Not free today">Busy</button>
<button class="b-deliverytime--slot b-deliverytime--slot-available" aria-label="Available Today" title="Today Free">Free</button>
I need to find every button with "--slot-available" and click it
Don't use forEach for asynchronous execution as it throws away the promises instead of awaiting them. Use a simple for loop:
const buttons = await page.$$('button[class*="--slot-available"]')
for (const button of buttons)
await button.click();
You can use a CSS selector to do the filtering:
const elements = await page.$$('button[class*="--slot-available"]');
elements.forEach(async element => {
await element.click();
});
The [attribute*=value] selector matches every element whose attribute value contain a specified value.

Can't select and click on a div with "button" role

I'm trying to click on a div that has a role="button" attribute,
Even though I'm not using it trying to get it by its DOM path is not working either.
What I've tried:
try {
let Button = await this.page.$("div.class1.class2 > div");
await Button.click();
console.log("Clicked");
} catch (e) {
console.log(e);
console.log("No button");
}
The error I get is:
TypeError: Cannot read property '$' of undefined
I tried to get to the div by the div that contains it which does have 2 classes I can relate on but it doesn't seem to work.
Is there a way to get an array of all the divs with role="button" and click only on the one that has a span inside it with a specific text?
Remove this keyword to fix the TypeError error.
let Button = await page.$("div.class1.class2 > div");
To get an array of all the divs with role=button and Specific text text:
const buttons = await page.$x('//div[#role="button"][text()="Specific Text"]'); // returns: <Promise<Array<ElementHandle>>>
But I would recommend adding waitForXPath method to wait for the element.
Full example:
try {
const button = await page.waitForXPath('//div[#role="button"][text()="Specific Text"]');
await button.click();
console.log("Clicked");
} catch (e) {
console.log("No button", e);
}

With Puppeteer how can I click the parent element of my selector?

The markup i have to work with looks like this:
<label>
<input type="radio" name="myfield" value="Yes" size>
</label>
I want to call page.click(selector) with the radio as the selector, but I can't. I don't think it is visible because of the size attribute.
My javascript looks like this:
const page = await browser.newPage();
const selector = 'input[name="myfield"]';
await page.click(selector);
So I would like to target and click the parent label element.
How do I change the value of my selector constant to target the label?
Sorry, I didn't explain very well. By can't, i mean that the element is not visible and therefore i don't believe it can technically be clicked. Therefore I think i need to target the label which is visible, but i don't know how I target it
not visible or not visible at the moment?
Have you tried to use waitForSelector(selector) ?
const page = await browser.newPage();
const selector = 'input[name="myfield"]';
await page.waitForSelector(selector); // waiting here before click
await page.click(selector);
Or something like:
const page = await browser.newPage();
const selector = 'label';
await page.waitForSelector(selector);
await page.evaluate((_) => {
document.querySelector('label > input[name="myfield"]').parentElement.click()
});

puppeteer howto get element tagName

I would like to get an element's tagName. Should be button in following example.
const puppeteer = require('puppeteer')
async function run () {
const browser = await puppeteer.launch({headless: false})
const page = await browser.newPage()
const html = `
<div>
<button type="button">click me</button>
<span>Some words.</span>
</div>
`
await page.setContent(html)
const elements = await page.$$('button')
const tagName = await elements[0].$eval('*', node => node.tagName)
console.log(tagName) // expect to be 'button'
await browser.close()
}
run()
The error message said Error: failed to find element matching selector "*"
I can tell elements matched one element as elements.length is 1
Where is wrong?
========== Edit ==========
Let's say I already had elements beforehand, how to get the tagName out of it.
Thanks!
Try using page.$eval to select the button, and then get the tagName from the button:
const tagName = await page.$eval('button', button => button.tagName);
If you already have an elementHandle like elements[0], you can get an attribute from that element by passing it through page.evaluate:
const tagName = await page.evaluate(
element => element.tagName,
elements[0]
);
It appears your elements is an array of ElementHandles.
In that case, there may be a slightly more straightforward syntax:
const tag_name = await (await elements[0].getProperty('tagName')).jsonValue()
This does not involve referring to the page object.
Thanks!

UWP/WinJS: show a html page in a pop-up window

I am working on a JavaScript based UWP app. Now I need to dynamically show a html page(with a url) in a pop-up window.
I did some search, there is a ContentDialog I can probably use:
var object = new WinJS.UI.ContentDialog(element, options);
but I cannot find any JavaScript sample code for it. I couldn't figure out what should I pass as "element" and how I put the html in ContentDialog.
Thanks in advance for any help.
The WinJS playground shows you how to use the ContentDialog: http://winjs.azurewebsites.net/#contentdialog
The element you pass is the Html element you want to initiate as the dialog.
<div id="myDialog">I am the going to be the dialog content.</div>
 
var element = document.getElementById('myDialog');
var options = {
title: 'Main instruction',
primaryCommandText: 'Ok',
secondaryCommandText: 'Cancel'
};
var dialog = new WinJS.UI.ContentDialog(element, options);
If you want to set the dialog content dynamically you can do so with
var webview = document.createElement('x-ms-webview');
webview.src = 'http://stackoverflow.com';
dialog.element.querySelector('.win-contentdialog-content').appendChild(webview);
dialog.show();

Resources