Is there any way to close popup while running headless chromium? - python

I am using the Playwright library to get data from a website. The issue is that website shows a popup when it open which results in stuck processes since the program is not able to get any button due to the popup.
Is there any way to close a popup each time it appears using the playwright?
Edit:
Page is creating a pop-up. I inspect the page and learnt that they are not using the modal for the pop instead they wrote the inline css and decorated a div as the popup.

Closing actual popups
I think browser.once("targetcreated", ...) as described in this issue https://stackoverflow.com/a/57246544/2202112 could be something that you are looking for.
It allows you to setup a callback on newly created targets.
For reference, see puppeteer docs on "targetcreated"
Closing modals
Find the selector for the button that dismisses the modal, for example .button-close or .button-dismiss.
Use the page.click(selector, [options]) method to click the button before continuing further scraping

As the documentation says Playwright will automatically dismiss all modal dialogs if there are no listeners of "dialog" event. Default behavior is essentially equivalent to
page.on('dialog', dialog => dialog.dismiss());
if it doesn't close in your case, it's most likely not a modal dialog (or a bug in playwright).
If the page opens another popup page, you can follow this guide but from your description it sounds more like a modal dialog.

Related

How to talk with alert from page and not browser with Selenium

This is what the alert looks like. It reads: The proxy it3.prmsrvs.com is requesting a username and password I have a program in Selenium that automates a certain amount of stuff on a website.
For some reason (this has been encountered also by my colleagues when using the browser normally without automation) there is the possibility of a pop-up showing in the webpage at a random point.
My program's objective is to load a page, get a list of all the elements corresponding to a specific tag and then click on them one by one. They all open in a new tab.
There is the possibility of a pop-up to show in the page after closing one of the tabs.
This pop-up asks for a login but all I have to do is dismiss it and the page will keep working like always.
Now, I've seen people using driver.switch_to.alert.dismiss() but this doesn't seem to work on this page.
I checked the function on a very basic js alert and the dismiss works perfectly, so I think it's the type of alert that is the issue.
I can't inspect the page so I don't know how to retrieve the iFrame of this alert. (I saw this as a possible solution online)
What should I do?

How can I click "invisible" reCAPTCHA buttons using Selenium web automation?

I am using Python and Selenium to automate this website: https://prenotami.esteri.it
The script I made fills out a form and then clicks a button to advance to the next page. These actions are carried out using Selenium's find_element_by_xpath() function. Recently, the website added a reCAPTCHA that pops up after the button is clicked, and must be completed before advancing.
I have already written a Python script that is capable of surpassing this type of captchas by using the audio option. However, in this particular website, I am not able to find the xpath to the audio button of the reCAPTCHA. Although there is an iframe that contains the reCAPTCHA, there seems not to be anything inside it.
In the first attached image you can see how this website's reCAPTCHA looks like in HTML, compared to other website that is visible in the second image, where a #document can be seen inside the iframe.
My intention is to run this program using headless Chrome, so I can't relay in any mouse control functions offered by pyautogui for example.
I've been scratching my head around this problem for a while, so any advice is useful. Thanks!
Edit: after some research I have found that this type of reCAPTCHA that doesn't need to check a "I am not a robot" checkbox is called "invisible reCAPTCHA". The captcha only pops up if the detected activity is suspicious (for example clicking too fast). I have tried adding random waits and movements to mimic human behaviour, but the captcha still appears after some tries. Since I don't think there is a way to avoid the captcha from appearing 100% of the times, the question of how to click the buttons using Selenium's find_element_by_xpath() function remains the same. Leaving this as a note just in case someone finds it useful.
Ever tried to use the following function:
add_argument("-auto-open-devtools-for-tabs")
I managed to interact with captcha
If the position is always fixed, you can use PyAutoGUI to move the mouse and click on it
import pyautogui
pyautogui.click(100, 100) # button coordinates
Since, it is in iframe, we need to move our selenium pointing to iframe and then use your xpath.
driver.switch_to.frame("c-la7g7xqfbit4")
capchaBtn = driver.find_element_by_xpath("(//button[#id='recaptcha-audio-button'])[2]")

Selenium can't locate elements inside HTML doc within another HTML doc

I don't know what's exactly the thing that Amazon opens when you click the "buy now" button, I tryed to search on internet but couldn't find a clear answer. It could be a pop-up or an iframe, but they call it "popover" in their source code, which I have no clue what it is.
The point is, once you open this "popover", Selenium is unable to parse any part of that frame since it's a standalone separate HTML doc. I'm not sure if it's an iframe as I've never seen an iframe like that, so any guide I serached online about how to switch context using an Handler to an iframe doesn't work here. I couldn't find an ID, name, or anything significant to allow Selenium to parse the frame.
image showing the "popover"
If anyone has any clue how this HTML element is actually called and how to allow Selenium to parse it, please let me know, thanks.
I checked HTML of the page and here are my findings:
'Close' button is not in iFrame
Popup content itself is in iframe
See screenshot below:
What does it mean for you:
In order to click on the button 'Close' (e.g. by css selector button[class*='a-button-close']) you do not need to switch to any frames. If you are failing to click on the button - I would assume that you are missing selenium wait. There is a small delay after you clicking on "Buy Now" button and before popup actually loads - you need to explicitly wait for it to load. See https://selenium-python.readthedocs.io/waits.html for more details on selenium waits. I would recommend using visibility_of_element_located or visibility_of to wait for popup/button to appear (load) in your case.
If you did any operations in the popup itself (e.g. if you clicked on some links inside of it) - you most likely switched to the context of the iFrame with driver.switch_to.frame(iframe). In this case - you need to switch back to main context with driver.switch_to.default_content() in order to click on the 'Close' button (since it is outside of iframe).
I highly recommend learning runtime evaluate technique - it will save you hours on debugging your applications - see https://www.jetbrains.com/pycharm/guide/tips/evaluate-expression/
P.S. next time when asking question - please post your code (at least on high level) - it will help with localizing issue.

How to automate chrome extension that interacts with the parent webpage?

I want to automate the testing for a chrome-extension.
I have used selenium-python to automate the parent web-page , but i am unable to use selenium to automate the chrome-extension because selenium is bound to the web-page view,so i am not able to click the chrome extension icon present in the title bar of the google chrome. Due to this limitation, i tried using sikuli to click on the chrome-extension icon ,but i couldn't get the DOM of the chrome-extension popup HTML that appear when the extension's icon is clicked, as i had to access the text displayed by the extension's pop up html page and then evaluated it.My test failed.
I thought i could use shift_to_window() but in vain,because its a pop up html, and hence i cant shift.If instead i use sikuli ,as the test cases increased , the amount of pictures needed to automate it will also increase, so it won't be feasible.
Sample Screenshot,
In this picture,the web-store page is the parent page and the small popup in the right top corner,is the pop-up i am talking about, that appear after clicking the chrome extension . So basically i have to interact with that popup HTML.
I didn't quite understand why you can't automate whatever webpage you have with Selenium and what is the limitation you are describing. Perhaps an example such as screenshot or even a link to the relevant webpage can help. Furthermore, I don't understand why do being unable to extract DOM from a page is a limitation while using Sikuli. Sikuli has nothing to gain from the DOM, it purely based on visual content of the screen.
I would attempt to handle the popup you are describing using using standard Selenium functionality so something like this:
driver.switchTo().alert().dismiss();
There are additional alert handling options so you can choose what suits you most.

Selenium-Python: interact with system modal dialogs

I am running an app in the browser; and for some actions I was able to simulate actions with keystrokes; but I have a peculiar problem: some actions in my app cause system prompt to pop up, like for example for save or confirm quit.
Is there a way to control these in Selenium python? As example imagine to use keystroke to save a page; then the system dialog (which is not part of the web app), appear and ask you where to save the file. Or imagine the prompt that ask you if you are sure to close the browser window if you have multiple tabs open.
I did try to look for a different window, assuming that I can switch context between windows in the browser, but I find nothing beside the main app, because these are system windows. Is there a workaround for this?
If you are talking about system dialogs, then it's not possible to interact with them using selenium.
However, for browser popups (alerts), just navigate to the popup:
driver.switch_to_alert()
Then, use the methods from the Alert class to interact with the popup. The Alert class contains methods for dismissing, accepting, inputting, and getting text from alert prompts.
Some examples:
Alert(driver).accept()
Alert(driver).dismiss()
Alert(driver).authenticate()
Alert(driver).send_keys(keys_to_send)
Alert(driver).text()
see: https://seleniumhq.github.io/selenium/docs/api/py/webdriver/selenium.webdriver.common.alert.html
You could make usage of the Selenium methods to check current window and move to another one:
You can use
driver.window_handles
to find a list of window handles and after try to switch using following methods (selenium documentation).
driver.switch_to_alert()
driver.switch_to.active_element
driver.switch_to.default_content
driver.switch_to.window
Since the application you work on, seems to respond to Selenium commands here it is a working example about opening a popup window, switching selenium scope on it, extract data and close the popup.
The process is repeated for all the products:
for item in driver.find_elements_by_class_name("products"):
item.click() # clicking on item activate a popup
driver.switch_to_alert() #switch to new window
# Get data
driver.find_elements_by_css_selector(".ui-dialog-titlebar-close.ui-corner-all")[0].click() #close window

Categories