I'm having a hard time initiating the 'print' event on google chrome using selenium.
I've tried all the following both on OSX and Windows with no luck. For OSX I've replaced Keys.CONTROL with Keys.COMMAND/Keys.META.
driver = webdriver.Chrome()
driver.get("http://google.com")
# 1st try
actions = ActionChains(driver)
actions.move_to_element(driver.find_element_by_tag_name('body'))
actions.key_down(Keys.CONTROL).send_keys('p').key_up(Keys.CONTROL)
actions.perform()
# 2nd try
ActionChains(driver).key_down(Keys.CONTROL).send_keys('p').key_up(Keys.CONTROL).perform()
# 3rd try
ActionChains(driver).send_keys(Keys.CONTROL, "p").perform()
# 4th try
driver.find_element_by_tag_name("body").send_keys(Keys.CONTROL + 'p')
None of the above did the trick. The only method that worked is driver.execute_script("window.print()"), but that is not the behaviour I'm looking for in this case.
Chrome driver version 80.0.3987.106.
Any ideas? Is there a way to initiate the 'print' event without the use of hotkeys?
A few words:
You should not be testing print dialog as it is a part of browser functionality and not related to your application.
If your usecase is to test the browser but not the web application you should be aware that sticking to key events is not the best option to proceed as if/when you come to the situation of tests execution in Selenium Grid or any form of Parallel Test Execution you may run intorace condition.
Solution
So the way to go is Window.print() function instead and you can use either of the following strategies:
Using execute_script():
driver.execute_script("window.print()")
Using execute_async_script():
driver.execute_async_script("window.print()")
Related
I am trying to automate a process to download data from a website. The code works if I run it step by step but if I run it all at once it fails. Giving the error
ElementNotInteractableException: Message: element not interactable
I have got around this using time.sleep(x amount of time) but it still seems to fail intermittently. I am having trouble implementing implicit waits. Any help would be appreciated. Code below.
import selenium
browser = webdriver.Chrome(executable_path=r'path\to\chromedriver.exe')
browser.get("https://map.sarig.sa.gov.au/")
browser.maximize_window()
browser.switch_to.frame(browser.find_element_by_id('MapViewer'))
browser.find_element_by_xpath('//*[#id="TourWidget"]/div[1]/span').click()
browser.find_element_by_xpath('//*[#id="menuAllMapLayers"]/div[2]/p').click()
browser.find_element_by_xpath('//*[#id="238"]/li[1]/div/div/span[1]').click()
time.sleep(3)
browser.find_element_by_xpath('//*[#id="238"]/li[1]/div/div/span[1]').click()
browser.find_element_by_xpath('//*[#id="238"]/li[3]/div/div/label/span').click()
browser.find_element_by_xpath('//*[#id="239"]/li[1]/div/div/span[1]').click()
browser.find_element_by_xpath('//*[#id="239"]/li[3]/div/div/label/span').click()
browser.find_element_by_xpath('//*[#id="menuActiveLayers"]').click()
browser.find_element_by_xpath('//*[#id="groupOptions238"]/span').click()
time.sleep(3)
browser.find_element_by_xpath('//*[#id="238"]/li[2]/div/div[3]/div[2]/span').click()
browser.find_element_by_xpath('//*[#id="groupOptions239"]/span').click()
time.sleep(3)
browser.find_element_by_xpath('//*[#id="239"]/li[2]/div/div[3]/div[2]/span').click()
Use ActionChains and get access to pause(3) instead of using sleep(3) but it could also help to use Waits and checking if your elements actually are "visible" rather than "present" (see expected_conditions)
It's a lot of dropdowns so maybe there are not visible all the time, but you can run these checks after doing a move_to_element() so it would actually be present.
I have a Python program that uses APScheduler and Selenium to automate webscraping. Basically it scrapes a particular website once every hour, and then schedules certain more detailed scrapes to happen at intervals.
The issue is that while I want to start the scraper, and then be free to use my computer for other work, Selenium will then automatically focus on the opened chrome tabs whenever a new scrape is started by APScheduler. Because of this, I am trying to find a way to have the new chrome windows open - but I don't have to focus on them. I've already tried headless and phantomJS, but the site is dynamically generated so these don't really work.
My current solution is to open the new window, minimise it, and then immediately shift back to the old window. To do this I want to perform a keyboard shortcut using ActionChains. I currently have this test code:
driver = webdriver.Chrome(ChromeDriverManager().install())
ActionChains(driver).key_down(Keys.CONTROL)
ActionChains(driver).send_keys(Keys.RIGHT)
ActionChains(driver).key_up(Keys.CONTROL)
Currently this code does nothing however. Is there anyway to fix this? I am using Jupyter Notebook and I am on a mac for reference.
NOTE: this code is being run apart from the main program, I am just using it to test if the script will work.
Try this out. You never .perform() it.
ActionChains(driver).key_down(Keys.CONTROL).send_keys(Keys.RIGHT).key_up(Keys.CONTROL).perform()
I am using webbroswer.open() in a loop to download multiple files at given intervals.
The issue I am having is that whenever the browser window opens, it becomes the primary window and thereby interrupts and disrupts my ability to use the computer. Downloading multiple files means this can last some time. The broswer continuously flashing open is obviously jarring.
Is there any way to instruct webbrowser to open the browser minimised by default or otherwise avoid this issue in some other ingenious way?
Much appreciated!
If you are open to using other modules I would urge you to look into selenium. This allows you to do many things, and one of them is to launch in headless mode (so as not to disturb you as it loads pages). The documentation is at:
https://selenium-python.readthedocs.io/
And you would be interested in the headless option
You would be advised though to make sure your script works without this enabled before you enable it though.
Sample code:
import selenium
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
my_options = Options()
my_options.headless = True # set to False for debugging!!
browser = webdriver.Chrome(options=my_options)
browser.get('http://www.google.com')
print('Done.')
You will need to download the proper drivers (just follow the instructions on the link I posted) for whatever browser you'd like. I picked Chrome, but they have Edge, Firefox, and Safari browsers as well!
Several times I have faced this issue: I run my Python-Selenium script using Firefox, but instead of browser window, updates downloading pop-up appears and I get WebDriverException: "The browser appears to have exited ". Just after download completed browser window opens, but script is already stopped.. So how can I avoid script exit and force webdriver to wait until Firefox updates completion...
Disable auto update by passing custom FirefoxProfile when you open the
browser.
from selenium import webdriver
fp = webdriver.FirefoxProfile()
fp.set_preference('app.update.auto', False)
fp.set_preference('app.update.enabled', False)
browser = webdriver.Firefox(firefox_profile=fp)
Another solution is to disable autoupdate manually Options>Advanced>Update by "Never check for updates" radio btn. In my case its better idea because I have full control of compability between FF and WebDriver version then. Once I want to move to newer/newest version I do it via Help>About Firefox or if Im interested in specific version I can always download it here
I'm using Python with Selenium 2.44. When the test fails, I can't just uncomment all the code before the failure when debugging it, because the driver will not be declared for the browser. Therefore, whenever I try fixing something, I always have to open a new browser in the test case. This is rather... slow since I have to login, which adds an additional 30 seconds (not devastating, but annoying). I want to know if there's a way for me to just continue a session, or do something that allows me to start the test midway through (so if I have the webpage open already, I can just immediately start clicking things rather than opening a new browser). Is this possible?
For example, if I had something along the lines of:
driver = webdriver.Firefox()
driver.get("google.com")
driver.find_element_by_xpath("//input[#id='gbqfq']").send_keys("cats" + Keys.RETURN)
This should open Firefox, go to google, and search for cats. Pretend like there's a ton of stuff you have to do before you can actually make it to the google page, though. Now if it were to fail on the search for cats, the only way I would be able to test to see if I fixed the code would be to rerun the test (webdriver.Firefox() would open a new browser). Rather than that, assuming I'd still have google open, I'd like the selenium test to just start off on the previous browser and google page (therefore saying the first step in the code would be the send_keys("cats")). Is this possible?
I think that this was a similar question, but it didn't get checked off as answered: How to resume browser session or use existing browser window with Selenium-Python?
This one also seems similar, only pertaining to Java: How do I rerun Selenium 2.0 (webdriver) tests on the same browser?
Thanks.
Look into pdb: https://docs.python.org/2/library/pdb.html
Placing this in your code will stop the progression of the test as is until you tell it to continue in your shell.
Using your code snippit:
from pdb import set_trace
driver = webdriver.Firefox()
driver.get("google.com")
set_trace()
driver.find_element_by_xpath("//input[#id='gbqfq']").send_keys("cats" + Keys.RETURN)
will stop your execution after getting the url, allow you to tinker, and then continue from where the test left off.
Alternatively, while debugging, you can just remove the driver.quit() statement, wherever it happens to be, which will keep the browser open wherever your assertion failed. But if you're using a framework like Django with the LiveTestServer Client, you won't have access to browse the site further. pdb will allow you to keep the test server active.