I have a button nested in this video player that I am trying to simply click. Any idea how do i select?
await page.waitForSelector('.icon-play');
await page.click('.icon-play');
await page.waitFor(6000);
}
<a tabindex="-1" href="#" role="button" class="icon-play comp largePlayBtn largePlayBtnBorder" aria-label="Play clip" data-order="1" data-plugin-name="largePlayBtn" style="display: block;"></a>
I had the same problem a while back. A nested link inside a image.
This is due to the fact that the element needs to be visually clickable. You can perform a simple javascript click action using the HTMLElement.click() to bypass the puppeteer click action.
page.$eval(`HTMLElementSelector`, element =>
element.click()
);
As you're clicking a link, which implies navigation you would want to englobe that inside a promise. Something like that should do the trick.
await Promise.all([
page.$eval(`HTMLElementSelector`, element =>
element.click()
),
await page.waitForNavigation(),
]);
this answer is to make a clear understanding of why the puppeteer's click doesn't work sometimes.
Puppeteer's API has different semantics from the native browser API.
Puppeteer's page.click() seems like a straightforward wrapper on the browser's native HTMLElement.click(), but it actually operates quite differently.
working of page.click()
when we click using page.click() instead of invoking the click event handler directly on the element as the native HTMLElement.click() does
Puppeteer scrolls the element into view
moves the mouse onto the element
presses one of a few mouse buttons
optionally triggers a delay
then releases the mouse button
You can also trigger multiple clicks. In other words, Puppeteer performs a click like a human would.
That's why when we click page.click() it clicks at (x,y) position of the screen as a human would. So, sometimes we don't see expected results as it doesn't show any error and it shouldn't, we think that page.click() is not working.
So, the easiest solution is to use page.evaluate() and click with native browser API.
Solution
await page.evaluate(() => {
document.querySelector('selector').click();
});
Related
Below is a screenshot of a webpage that I am trying to write a Cypress test for.
As you can see, I have managed to write "teladoc" into the input box, but I now need to click the dropdown menu to navigate to a different page.
I am not able to get the ID, etc. of the dropdown menu.
When I try to inspect the dropdown menu, the page reloads and the dropdown disappears.
Does someone know how I can inspect this? I tried through the cypress explorer too, but it reloads in that beforehand too.
Since the locator is not there, You can play around with Keypress. The idea is when you have typed and there is the suggested list, you can first press the down key and then enter key. This might result in flaky tests as you don't know how much time does it take for the suggested item to appear.
cy.get(selector).type('{downarrow}{enter}')
You can also directly use contains. If this works this way the tests won't be flaky. You can play around with the timeout value.
cy.contains('Teladoc Health Inc - United States', {timeout: 5000})
.should('be.visible')
.click()
Open the browser console and type this
setTimeout(() => { debugger; }, 5000)
I am having trouble with running code only when a toolbar button is clicked. Here is my code:
$(document).on('click', `#toolbar-markupTool`, function(e) {
console.log('hi');
});
This works with anything except the markupTool icon... lucky me! I think this is due to there being an event that hide the toolbar that is handled by the markups gui extension. When the icon is clicked, the toolbar gets hidden, so my guess is that my event doesn't get executed because the element is hidden now.
The reason why I absolutely need to do it this way because I have an element that captures a screenshot that must absolutely only be shown when markups mode is activated. Does anyone have any idea how I could solve this issue?
You can take advantage of EXTENSION_ACTIVATED_EVENT filtering by extensionId ("Autodesk.Viewing.MarkupsGui") or TOOL_CHANGE_EVENT filtering by toolName("markups.core").
I'm navigating with Puppeteer around a React website.
Two sample lines of code:
await page.waitForSelector('a.btn-lg[data-target="#loginModal"]');
await page.click('a.btn-lg[data-target="#loginModal"]');
With a sufficient slowMo value, the effects are consistent - the button gets clicked every time.
However, without slowMo, sometimes the button does get clicked, and sometimes it doesn't (a window wired to it doesn't open).
It happens for a lot of elements, not just this one button in particular.
I just started using Puppeteer, and it looks like I'm either misusing the library, or the website somehow screws up my efforts.
Please tell me why sometimes the effects of clicking are visible and sometimes not, and how to remedy it.
UPDATE:
Code such as this does not work either.
await page.evaluate(() => (document.querySelector('span.pum-close') as any).click());
await page.$$eval('span.pum-close', elements =>
elements[0].click()
);
I'm making a chrome extension that uses pageAction.
I can set when it shows whether I want it to have a popup or handle the click myself.
What I want to do is handle the click myself, but with certain scenarios I don't want to process the normal code, and want to show the user a message. Preferably with a popup.
But it seams I can either make the pageAction have a popup or have an onClick. But not both.
I can show an alert, but that is ugly.
Currently, there is no "neat" or official way to handle both. You can just do either. But there are some work arounds that some Google extension product have done.
First of all, set it up to show the popup. And within your pageAction popup, you can have the initialization code to be something like this:
Page Action Popup:
function init() {
if (getClickBehaviour() == 'popup')
handlePopup();
else
openPage();
}
function getClickBehaviour() {
return localStorage['CLICK_BEHAVIOR'] || 'popup';
}
function openPage() {
chrome.tabs.create({url: 'http://google.ca'});
window.close();
});
}
init();
Then you can let your options, set the click behavior. If you want different behaviors on each click, you can do that too.
As you noticed, we are closing the popup right after for the "default" behavior that we don't want the popup to show. That is currently the only way to implement different behaviors.
I haven't tested this myself yet, but have you tried setting the popup to the empty string when you want to handle the click (chrome.pageAction.setPopup('')) and to your popup when you want to show a message. I'm not perfectly sure if the onClicked event handler gets called in that case (where the popup is dynamically set to the empty string), but it's worth looking into.
As far as I know, there is generally no way to programmatically open a popup window for a page or browser action. (Which is too bad, I would love this functionality; but you can imagine some of the annoyances if this were possible.)
I have a group of links on a page. when the user clicks a link it triggers an asynchronous request and a content area on the page is updated with the response html.
This works fine, except for if the user clicks the link with the 'middle-button' (or mouse wheel, whatever it's called!). Then a new tab opens and the response gets returned and rendered to that tab.
Is there any way for me to prevent this from happening?
catch the link with javascript and override the default link behaviour.
like this:
$('a.ajax').click(function(e){
e.preventDefault();
// do ajax stuff, and add an onfinish function that does
// something like document.location.href = this.attr('href');
});
You don't have to do the document.location.href, as I just noticed that a content area is updated. Just catch the default behaviour with the e.preventDefault();
// edit
The preventDefault won't stop the middle mouse button... Have you considered not using tags? I know it should be accessible so maybe a span containing the link, so you can add the onclick event on the span and hide the link with css?
Unfortunately no, Javascript wont have access to that sort of control for security reasons as it would be wide open for abuse.