Selenium can't find elements until I inspect the page - selenium-webdriver

I have quite a weird problem.
There's a website that has the following two buttons (I can see them when I inspect the page):
button 1
<ul class=" _3dEhb">
<li class = " LH76I">
<a class="-na14 _81NM2" href="/preview/">
<span class="g47FY 10XF41"</span>" preview"
<li class = " LH76I">
<a class="-na14 _81NM2" href="/launch/">
<span class="g47FY 10XF41"</span>" launch"
I'm using the python selenium code
buttons = driver.find_element_by_class_name('LH76I')
if I run it without inspecting the webpage, this code gives me an empty list.
However, if I debug and I inspect the webpage, the same code gives me 2 items in the list.
What am I doing wrong?
Thanks

You should use driver.find_elements_by_class_name instead because you are trying to get a list of elements with same identifier. Try the following code:
buttons = driver.find_elements_by_class_name('LH76I')
Then, if you want to click or something, you would do:
buttons[0].click()
EDIT - You can try the way the list items are generally extracted:
main_list = driver.find_element_by_class_name('_3dEhb') //gets the main ul element
List<WebElement> list_items = main_list.findElements(By.tagName("li"));
for x in range(0, len(list_items)):
{
// whatever you want to do with the item
}

Related

dir-pagination-controls only showing first 10 items. Angularjs

<tr dir-paginate="plan in access |itemsPerPage: 10" total-items="planCount" current-page="current">
<td>{{plan._id}}</td>
<td>{{plan.name}}</td>
<td>{{plan.email}}</td>
<td>{{plan.contactNumber}}</td>
<td>{{plan.accessToken}}</td>
<td>{{plan.downloadSpeed | toMBPS}}</td>
<td>{{plan.uploadSpeed | toMBPS}}</td>
<td>{{plan.issueTime}}</td>
and this is the directive
<div class="text-center">
<dir-pagination-controls auto-hide="false" on-page-change="pageChanged(newPageNumber)"></dir-pagination-controls>
</div>
and this is the angular code
$scope.planCount = 0;
$scope.current = 1;
$scope.pageChanged = function(value) {
console.log("Going to page" + value);
}
The data is coming from the server, but that is working fine. I have logged the data, and I am receiving the complete data. Also, it is the registering the changed page number correctly.
Still, it only shows the first ten items, doesn't matter on what page number I am.
Note: Don't mind the incomplete html. That is the only relevant part to my situation. I can't post the whole code.
Also, I am using this in a different page, but it's working fine in it.
<tr dir-paginate="plan in access |itemsPerPage: 10" total-items="planCount" current-page="current">
From above line remove total-items="planCount". It'll work here too.

How to check the state of element in selenium webdriver

Trying the below code to get the total number of number elements in the different pages. The while condition is getting true and the loop gets executed, but after reaching the last page, the condition is not getting false.
I'm iterating the loop by clicking on "next" button till it is enabled and have to stop the loop execution when this condition becomes false.
Please advice and help me out here. Have tried isEnabled(), isDisplayed as well.
Last Page HTML mark-up
<ul class="pagination-list">
<li class="disabled">
<a>
<span class="icon-next"></span>
</a>
</li>
</ul>
Selenium-
while(driver.findElement(By.xpath("//li[not(contains(#class, 'disabled'))]/a/span[(contains(#class, 'icon-next'))]"))!= null)
{
((JavascriptExecutor)driver).executeScript("window.scrollTo(0, document.body.scrollHeight)");
driver.findElement(By.className("icon-next")).click();
ActiveEnrollUserCounts = driver.findElements(By.xpath("//*[#id='usersList']/tbody/tr"));
uTotal = uTotal + ActiveEnrollUserCounts.size();
}
System.out.println("Active Enrolled Users Count: " +uTotal);

Can't select an md-select dropdown option using Selenium

I have an angular-material dropdown with a set of options, and am attempting to select one of the options. I'm selecting them as follows:
html file:
<md-select name="myDropdown"
ng-model="addCompany.details.someModel"
ng-change="addCompany.swapDisplayedAreas()"
required>
<md-option value="Company A">Company A</md-option>
<md-option value="Company B">Company B</md-option>
</md-select>
python test:
input = self.browser.find_element_by_name('myDropdown')
input.click()
choice = self.browser.find_element_by_xpath("//*[contains(text(), 'Company A')]")
choice.click()
However, no matter how I try to select the option, I either get the following error:
selenium.common.exceptions.WebDriverException: Message: Element is not
clickable at point (750, 423). Other element would receive the click:
<md-backdrop style="position: fixed;" class="md-select-backdrop
md-click-catcher ng-scope"></md-backdrop>
Or I can see that the element is clicked on, but that the dropdown still stays pulled out. Attempting to click on any other element on the page while the dropdown is still pulled out gives a similar md-backdrop would receive the click error.
Any idea how I can choose a dropdown selection for an md-select element? I've tried disabling md-backdrop for my input elements without any success.
You should try using WebDriverWait to wait until options open from the dropdown and getting visible and clickable before click as below :-
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
#find dropdown and click to open options
input = self.browser.find_element_by_name('myDropdown')
input.click()
#now wait until options getting visible and clickable
choice = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "md-option[value = 'Company A']")))
choice.click()
I would guess the issue may be one of the following:
There is another element on the page with the text "Company A" and that element is trying to be clicked even though the dropdown option is clearly the element you want selenium to click. This is because selenium clicks the first element that satisfies the identifier. To check if this is the problem I would use the find elements and check how many elements are found. If that is the problem try using the css selectors such as value.
If you are using chrome I came across a similar problem with the chrome webdriver when testing an angular application.
This is the issue https://code.google.com/p/selenium/issues/detail?id=2766
I tried elegant workarounds but nothing worked...in the end I used the solution by Lukeis.
In java
int n=10;
String errorMessage;
for (int i=1; i<=n; i++)
{
try {
clickThis.click();
break;
} catch(WebDriverException driverException) {
Thread.sleep(1000);
errorMessage = driverException.toString();
}
if(i==n)
{
Assert.fail("Failed to click "+n+" times \n" + errorMessage);
}
}
It pretty much tries to click the element 10 times.

Ruby/Selenium value into array

I need some help in Ruby/Selenium
i have a few elements on page like this:
<a class="Name" title="Migel" href="/profiles/users/_1324567980000000c/">Migel</a>
i'd like give HREF string value into array.
when i use "find_element" - ALL OK:
profile = driver.find_element(:xpath, "****").attribute ('href')
but page contains a lot of such elements, and i try to use
profile_array = driver.find_elements(:xpath, "lbuh-bluh").attribute ('href')
naturally that attribute ('href') dont work with array.
how can I do in this case?
in general, my task in implementing "random click" on page and i want collect all "href" elements which i need into array, and then realize something like this:
array[srtring1, string2....stringN].sample.click (schematically)
would just mapping over elements and get href attribute be sufficient?
profile_array = driver
.find_elements(:xpath, "lbuh-bluh")
.map { |el| el.attribute('href') }
I see that this is some sort of parsing html with Ruby, if this is the case why dont you use the Nokogiri gem, lets say you have something like:
<div id="funstuff">
<p>Here are some entertaining links:</p>
<ul>
<li>YouTube</li>
<li><a data-category="news" href="http://reddit.com">Reddit</a></li>
<li>Kathack</li>
<li><a data-category="news" href="http://www.nytimes.com">New York Times</a></li>
</ul>
</div>
Which is the content of a file called lets say: selenium.html located at your Desktop: C:\Desktop\selenium.html
here is the ruby code that handels that:
page = Nokogiri::HTML(open("C:\Desktop\selenium.html"))
links = page.css("a")
profile_array = []
links.each{|ref| profile_array << ref["href"] }
puts profile_array
=>http://youtube.com
=>http://reddit.com
=>http://kathack.com/
=>http://www.nytimes.com

Selenium Web driver: How to get preceding element from a nested span text using Java code?

I have a web page with below HTML format. This is just a sample and a part of code.
<div id="content">
........... Many other tags go in here......
<div id="1234"> // This id number is not constant and so cant hard code in xpath
<img class="float-right ng-scope" width="85" data-ng-click="highlightItem()" data-ng if="showThumbnail" ng-src="/server/image" src="/server/image">
<p>
<span data-ng-transclude="" data-ng-class="{ selected: isActive }">
<span class="ng-scope">My sample text</span>
<br class="ng-scope">
</span>
</p>
</div>
</div>
I have the text "My sample text" as my input. (There are many such div blocks and each has different span text). With this, I need to find the img element and click on it. I tried the below code : (referenceText variable = "My sample text")
String xPath = "//div[#id='content']//span[contains(text(),'" + referenceText + "')]";
// Get element of the text i.e get span element
WebElement element = getWebElementByXpath(getWebDriver(), xPath); // Gets span element
// Works fine !
// Get its parent element which is again another span
WebElement parentElement = getParentElement(element, xPath); // Gets next level span
// Works fine !
// Get its parent element p
WebElement grandParentElement = getParentElement(parentElement, xPath);
// Does not get its parent element 'p' instead return span element again
// Get preceding element for p which is img element
grandParentElement.findElement(By.xpath("./preceding-sibling::img")).click();
// Does not work as element p is not obtained.
getParentElement method is as below:
public static WebElement getParentElement(WebElement element, String xPath){
return element.findElement(By.xpath((xPath + "/..")));
}
Problem : I am able to get the span element and its parent span element but unable to get the p element and its sibling element img. I want to get img element using the span element. Any help on this would be great ! Thanks in advance.
Try the below XPAth for the image tag having "My sample text" as span value.
//div[#id='content']//div[.//span[span='My sample text']]/img
Refer http://www.xpathtester.com/xpath/b1d50008dd4be8ab7545548c4b8238f5
Simple open browser and check unique css locator, then check if that locator works for U in java code.
Try this xpath for getting grandparent 'p' from the 'span', with text "My sample text":
//span[.='My sample text']/../..
Try this xpath for getting the sibling 'img' of grandparent 'p', from the 'span' with text "My sample text":
//span[.='My sample text']/../../preceding-sibling::img
Try out with:
//span[.='My sample text']/ancestor::div/img
Thanks all for your help ! The below Xpath worked fine for me.
String xPath = "//div/p/span/span[contains(text(),'My Sample Text')]/../../..//img"

Resources