scroll a scrollable element using selenium for python - python

I am wondering how to scroll on a scrollable element in a web page. I found plenty of answers about how to scroll the whole page (working well) but here it's an inner specific div that is scrollable that I want to scroll to the bottom.
How can I do that with selenium for python?

I ran into a similar issue and solved it like this:
If this is your HTML:
<ul class="list">
<li class="list__element">1</li>
<li class="list__element">2</li>
<li class="list__element">3</li>
<li class="list__element">4</li>
<li class="list__element">5</li>
<li class="list__element">6</li>
<li class="list__element">7</li>
</ul>
Select all the child elements of your list like so:
list_elements = driver.find_elements(By.CLASS_NAME, 'list__element')
After that, you can loop over that list and scroll to a specific item.
Note: If your list progressively loads new list elements you need to accoaunt for that.
for comment in comments:
ActionChains(driver)\
.scroll_to_element(comment)\
.perform()
time.sleep(.1)

Related

Selenium [python] not clicking an <li> button

So I have been trying to use selenium to click an <li> button on an HTML which is in a <ul> tag and looks something like this:
...
<ul id="ulVisualization">
<li class="active" id="liMap">Map</li>
<li id="liBar" class="">Bar</li>
<li id="liLine">Line</li>
</ul>
...
I have been using the following command to get to the element using XPATH:
WebDriverWait(driver, 50).until(EC.presence_of_element_located((By.XPATH,"//li[#id='liBar']"))).click()
Yet for some reason that I have not been able to identify, this command is not able to find/click that button and the command hits its time-out.
I have even tried:
driver.find_element_by_xpath('//li[#id="liBar"]').click()
But that too was of no avail, throwing an error message saying NoSuchElementException: Message:
I would appreciate any and all help and thank you very much in advance.
EDIT:
Additionally, I have noticed that when I click on the button manually the HTML modifies to:
...
<ul id="ulVisualization">
<li class="" id="liMap">Map</li>
<li id="liBar" class="Active">Bar</li>
<li id="liLine">Line</li>
</ul>
...
Revealing the data I am trying to acquire later in the HTML code, which was not available before I clicked the button manually.
Since you want to click on the Element, try element_to_be_clickable, instead of presence_of_element_located
WebDriverWait(driver,30).until(EC.element_to_be_clickable((By.XPATH,"//li[#id='liBar']"))).click()
Make sure the locator you are using is Unique, that is 1/1. Link to Refer
And also check if the Elements are in an iframe or in an shadow-root or Trying to find Element in a newly opened browser tab.
If none of them work, apply some time.sleep() and check if it works.

Iterating in dropdown-menu

i'm having some troubles with trying to get a list in python..
I'm using Selenium Web Driver, Chrome specifically, and i have the next "button" :
<button id="btn" class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown" aria-expanded="false">Nope</button>
<ul id="ulDropdownNivel2" class="dropdown-menu">
<li>
text1
</li>
<li>
text2
</li>
<li>
text3
</li>
</ul>
So.. i have tried to use Select.class of Selenium Wd but, it's a button, and the class can't be used there... tried using it on the <ul> but it can't use Select neither...
Can't use smh like:
dropdoun = Select(driver.find_element_by_id('ID'))
for elm in dropdoun{ print(elm.text())}
Tried to figure a way to iterate through items... but i didn't get anything
i figured a way to click by xPath but, it doesn't work to me, cause text1, text2, text3 and so changes the order everytime you open the web
Any idea?
EDIT:
What i need here, is to iterate trough each item, and select the one that match with "text1", "text2" or "text3...
I think you should click button for dropdown will be opened:
opendropdownButton = driver.find_element_by_id("btn").click()
//here should be wait if now works
dropdownElements = driver.find_elements_by_xpath("//ul [#id="ulDropdownNivel2"]//a")
for elm in dropdownElements{ print(elm.text())}

Why did changing my xpath make my selenium click work consistently?

I am running a series of selenium tests with python. I have a navigation on the page I'm testing that has this structure:
<ul>
<li class="has-sub">
<a href="#">
<span> First nav </span>
</a>
<ul style="display:block">
<li>
<a href="#">
<span> First subnav </span>
</a>
</li>
<li>...</li>
<li>...</li>
<li>...</li>
</ul>
</li>
<li>...</li>
</ul>
Now I am clicking on the first subnav, that is the first span, but clicking on First nav to open up that list then first subnav. I implement a webdriverwait, to wait for the element to be visible and click on it via it's xpath,
//span[1]
I often got timeout exceptions waiting for the subnav span to be visible after clicking on the nav, which made me think something was wrong with clicking on the first nav to open up the list. So I changed the xpath of the first nav (//span[1]) to
//li[#class='has-sub']/descendant::span[text()='First subnav']
and I never get timeout exceptions when waiting for subnav span to be visible now. So seems like it's always clicking on the nav span every time to open it up and give me no timeout when trying to get to the subnav. Anyone have any idea why that is?
Here is my python code as well:
inside LoadCommPage class:
def click_element(self, by, locator):
try:
WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located((by, locator)))
print "pressing element " + str(locator)
self.driver.find_element(by, locator).click()
except TimeoutException:
print "no clickable element in 10 sec"
print self.traceback.format_exc()
self.driver.close()
inside main test (load_comm_page is an instance of LoadCommPage, where click_clement is defined):
load_comm_page.click_element(*LoadCommPageLocators.sys_ops_tab)
And another class for the locators:
class LoadCommPageLocators(object):
firstnav_tab = (By.XPATH, "//li[#class='has-sub']/descendant::span[text()='First nav']")
Xpath indexes begin at one, not 0 so the Xpath
//span[1]
is looking for the first span element in the html. Whereas
//span[2]
will look for the second span.

Selecting an option from drop down that opens up on hover

Need help in selecting an option from a drop that opens up on hover, here is the html i'm currently looking at or you can just look into the attached image -
<ul id="yui_3_7_0_4_1390312781452_393" class="dropdown-menu">
<li id="yui_3_7_0_4_1390312781452_392" class="action" value="4001">
Promising
</li>
<li class="action" value="4003">
In Discussion
</li>
<li class="action" value="4004">
Phone screen
</li>
<li class="action" value="4005">
Interview
</li>
<li class="action" value="4006">
Offered
</li>
<li class="action" value="4007">
Hired
</li>
And here is the code i'm trying -
strings = driver.find_elements_by_class_name("action").text
for text in strings:
if text=='Offered':
text.click()
Using a CSS Selector, you could click it by doing:
driver.find_element_by_css_selector("ul.dropdown-menu[id^='yui'] li[value='4006']").click()
In order to achieve drop down menu selection mentioned in the question, you'll first have to mouse hover to drop down menu then hover mouse over element to select and the click on the element. Following is Java code, but the logic will help you to implement it in Python:
WebElement dropDownMenu = driver.findElement(By.id("yui_3_7_0_4_1390312781452_393"));
WebElement elementToSelect = driver.findElement(By.xpath(".//li[contains(text(), 'Offered')"));
Actions action = new Actions(driver);
action.moveToElement(dropDownMenu).moveToElement(elementToSelect).click().build().perform();
try this (ref:http://allselenium.info/mouse-over-actions-using-python-selenium-webdriver/)
from selenium.webdriver.common.action_chains import ActionChains
action = ActionChains(driver)
firstLevelMenu = driver.find_element_by_id("yui_3_7_0_4_1390312781452_393") #id of menu, or xpath of menu, whatever
action.move_to_element(firstLevelMenu).perform()
secondLevelMenu = driver.find_element_by_xpath("XPATH_OF_OFFERED")
action.move_to_element(secondLevelMenu).perform()
secondLevelMenu.click()

python, locating and clicking a specific button with selenium

Using python and selenium I need to locate and click a specific button on a webpage. While under normal circumstances this can be done with the commands
next = driver.find_element_by_css_selector(".next")
next.click()
that won't work in this case due to the webpages coding. Where both the button leading to the previous page and the one leading to the next share the same class name. Thus this code will only go back and forth between the first and second page
As far as I can tell the only way to tell the two buttons apart, is that the button leading to the previous page lies within
<li class="previous">
#button
</li>
and the one that leads to the next page lies within
<li class="next">
#button
</li>
Is there some way of having selenium only select and click the button that lies in the "next" li class?
The complete button code:
the previous button:
<li class="previous">
<a class="next" rel="nofollow" onclick="qc.pA('nrForm', 'f76', 'QClickEvent', '1', 'f28'); return false;" href="">
Previous
</a>
</li>
the next button:
<li class="next">
<a class="next" rel="nofollow" onclick="qc.pA('nrForm', 'f76', 'QClickEvent', '3', 'f28'); return false;" href="">
Next
</a>
</li>
I think you should use .find_element_by_xpath().
For example:
next = driver.find_element_by_xpath("//li[#class='next']/a")
prev = driver.find_element_by_xpath("//li[#class='previous']/a")
or:
next = driver.find_element_by_xpath("//a[text()='Next']")
prev = driver.find_element_by_xpath("//a[text()='Previous']")
With CSS selectors:
next = driver.find_element_by_css_selector('li.next>a')
CSS Selectors are cool and useful: http://www.w3schools.com/cssref/css_selectors.asp
XPATH, not so much - it should be used only as a last resort.

Categories

Resources