Clicking opens a new link - python

selenium/chromedriver
When clicking a button, a new tab is opened when I do it through a GUI browser.
Python Selenium seems to have no problem clicking the button, as it gives me no errors. The errors come in the next step, when I need to find an element in the clicked page. I had selenium take a screenshot and it still shows the first page.
Presumably it clicked the button, created a new tab, and didn't switch over?
How do I switch to the new tab, or even verify the new tab exists in the first place?
Thank you!

When you open a browser with selenium, it stores a handle for each tab/window it is controlling in a list called window_handles, for example:
from selenium import webdriver
driver = webdriver.Firefox()
print(driver.window_handles)
...should give you something like ['6b7af9bb-f299-462e-a79a-2b8fda63f388']
When you open a new tab, a new handle for that window/tab should be added to that list. To then switch to the tab you want, use driver.switch_to.window(), for example (continuing above example):
driver.switch_to.window(driver.window_handles[1])
Note: you could also use driver.switch_to_window, but this is deprecated in favor of the above example.
Also, just a tip for debugging, it can be helpful to use the python repl so you can follow what the browser is doing in real time.

Related

How to interact with a separate pop-up window/website with Selenium / Chrome Driver in Python?

I am trying to automate a process with Selenium, and am having troubles figuring out how to switch between open windows while the program is running.
After clicking on the button, it opens another website that has a separate url, which is unique each time it is opened. I need to switch Selenium from interacting with the original website to this new popup within the browser, caused by the original website. The new window shows that it is also controlled by Chromedriver with the bit at the top that says "Chrome is being controlled by automated test software." Additionally, the actual website opened will be the same, just the fine print after the '.com/' is different.
How would I go about doing this? Also, how would I switch back? (If this is even possible)
For example:
driver=webdriver.Chrome(service=s)
driver.get("https://originalwebsite.com/")
driver.find_element(By.XPATH, 'buttons-xpath').click()
# (popup opens up now)
# *switch to popup website here*
driver.find_element(By.XPATH, 'button-on-new-website-xpath').click()
driver.find_element(By.XPATH, 'second-button-on-new-website-xpath').click()
# *popup website closes*
# switch back to original website / window
Thanks!
I have tried to use driver.navigate in a variety of ways but generally have no clue what I am doing. Thanks again!
The comment from ALex Break led to the answer.
All I had to do was:
handles = driver.window_handles
driver.switch_to.window(handles[x])
#handles[x] is the index of the list handles that has the handle I want to switch
#to stored in it

Fails to perform keys down and hit enter in context menu python selenium

I want to login to a site. Right-click on one of the links and open in New Tab or New Window.
I have searched earlier here and googled around before posting it here. May be I am doing it wrong
button=browser.find_element_by_link_text('Menus');
action=ActionChains(browser)
action.context_click(button).perform() #--> Till here working fine, Right clicks on Menu
action.send_keys(Keys.ARROW_DOWN+Keys.ARROW_DOWN+Keys.ENTER).perform() #--> Not Working
I wouldn't go into that direction as performing context menu clicks will bite you back when you'll be running your Selenium tests in Parallel Mode
Instead of opening context menu and clicking I would rather recommend:
Extract href attribute from the link
Use Window.open() JavaScript function to open the link in the new tab
Use Explicit Wait to wail until number of windows becomes 2
Switch the context to the new tab
Example code:
button = browser.find_element_by_link_text('Menus')
href = button.get_attribute("href")
browser.execute_script("window.open('" + href + "')")
WebDriverWait(browser, 10).until(EC.number_of_windows_to_be(2))
browser.switch_to.window(browser.window_handles[1])

Python Selenium Firefox new tab without CONTROL + click

I want to click on an element(found by xpath) but if i use:
ActionChains(driver).key_down(Keys.CONTROL).move_to_element(myElement).click().key_up(Keys.CONTROL).perform()
-> I get a new tab but the current tab also Redirects to the page
So what I need is a way to perform a right click and choose "open in new tab" but that does not work for me.
I use this code but after I get into the context_menu nothing happens.
ActionChains(driver).context_click(myElement).send_keys(Keys.DOWN).send_keys(Keys.RETURN).perform()
Another way would be to click "myElement" with the scroll wheel button but i can not find the click method for that.
Thank you.
(I do not need anything with Control + mouse click :-) )
If the trouble is managing the window/tab focus, you could use window_handles as in this post ?
I didn't understand if you wanted to get control over previous tab or the next one. For the first tab, that would be something like
driver.switch_to_window(driver.window_handles[1])
Edit : try this (3 steps, requiring first to acquire the target, then opening a blank new tab, then reaching target)
from selenium.webdriver.common.keys import Keys
href = myElement.get_attribute("href")
current_page = driver.find_element_by_tag_name('body')
current_page.send_keys(Keys.CONTROL + 't') #open new tab
driver.switch_to_window(driver.window_handles[1])
driver.get(href)

selenium window_handles not correct when new window is opened wtih Python

I want to use selenium with Python to open multi-tabs in one browser and scraping the real-time betting odds simultaneously with multi-tabs.
The website home page generate a list of games. However, there is no way to get the link of game unless you find the game element and use click()(the website is ajax heavy), which open the game in the same tab. My solution to open multi-tabs is to get the list of game then manually open new tab with home-page first loaded and then click on the game with different index in the list. However, I find the driver.window_handles array always include only one item, which is the current tab instead of all the tabs I opened manually in the browser.
Can anybody tell me what goes wrong or if you can give a better solution to this issue?
The problem is simplified as the code in following:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
# create a new Firefox session
driver_temp = webdriver.Firefox()
driver_temp.implicitly_wait(30)
driver_temp.get("https://www.google.com")
body = driver_temp.find_element_by_tag_name('body')
# manually open second tab
body.send_keys(Keys.CONTROL + 't')
driver_temp.get("https://www.google.com")
body = driver_temp.find_element_by_tag_name('body')
# manually open third tab
body.send_keys(Keys.CONTROL + 't')
driver_temp.get("https://www.google.com")
body = driver_temp.find_element_by_tag_name('body')
#print the number of window_handles
print len(driver_temp.window_handles)
I have opened 3 tabs, however the len(driver_temp.window_handles) is always 1
Selenium does not provide an API to manipulate browser tabs. You've probably noticed that applying the CTRL/COMMAND+T "hack" to open a new tab.
See more at:
Controlling firefox tabs in selenium
Opening a new tab in the same window session of the browser through selenium web driver command?
Instead, open up new browser windows.
Well, to be fair, it is important to mention that the behavior is quite different in Firefox and in Chrome - if you open new tabs in Chrome, selenium would see each tab as a window with it's own handle and you'll switch between them using switch_to.window() easily.

Python, Selenium Webdriver: The element is not visible for Firefox.

I'm trying to iteract with a webelement on a page that has edit link that opens a popup. In opened popup I have simple input field and Apply/Cancel buttons. In my script I do the following to enter some text to the input field:
def enter_text(self, text, action):
if self.is_element_present(self._input_locator):
self.selenium.find_element(*self._input_locator).send_keys(text)
if action == 'Apply':
self.selenium.find_element(*self._apply_button_locator).click()
elif action == 'Cancel':
self.selenium.find_element(*self._cancel_button_locator).click()
When I run my script in Chrome - everything works fine, all webelements are found and input text is entered to the field. But when I run exact same script in Firefox - it opens popup window (which means it became visible for Webdriver) with input field and 2 buttons but the text is not getting entered to the field which causes error:
ElementNotVisibleException: Message: u'Element is not currently visible and so may not be interacted with'
Why can this happen if the popup is actually opened (and I can see it) but Webdriver tells that it is not visible? Also, I put several sleeps just to get sure that popup loaded and then the text is entered but it did not help.
Any help will be appreciated.
Two ideas:
1: make sure your HTML is valid, eg by running it thru the w3c validator. broken html is a common cause of different behaviours in different browsers.
2: have you definitely switched selenium over to the popup, using, eg:
for handle in self.selenium.window_handles:
# identify popup window's handle somehow
self.selenium.switch_to_window(handle)
As an aside, if you haven't come across selenium.implicitly_wait(3), it's dead useful as a way of avoiding time.sleeps and wait-for constructs..
Witch Firefox version and Webdriver version are you using?
Please try the following:
Update Webdriver to the last version
If you are using firefox 17-18, downgrade it to lower version (I guess FF12 will work)
Please try that and tell me what happens,
Regards

Categories

Resources