Official locator strategies for the webdriver
Yes, you saw it right.
As per the current WebDriver - W3C Candidate Recommendation the Locator Strategies enlisted are as follows:
- "css selector": CSS selector
- "link text": Link text selector
- "partial link text": Partial link text selector
- "tag name": Tag name
- "xpath": XPath selector
Snapshot:
However, the JsonWireProtocol was once used to support the Locator Strategies enlisted below, but currently the documentation clearly states its Status as obsolete:
- class name: Returns an element whose class name contains the search value; compound class names are not permitted.
- css selector: Returns an element matching a CSS selector.
- id: Returns an element whose ID attribute matches the search value.
- name: Returns an element whose NAME attribute matches the search value.
- link text: Returns an anchor element whose visible text matches the search value.
- partial link text: Returns an anchor element whose visible text partially matches the search value.
- tag name: Returns an element whose tag name matches the search value.
- xpath: Returns an element matching an XPath expression. The provided XPath expression must be applied to the server "as is"; if the expression is not relative to the element root, the server should not modify it. Consequently, an XPath query may return elements not contained in the root element's subtree.
Snapshot:
The change was propagated through the respective client-specific bindings. For the Selenium-Java clients here is the client code where we have the switch case working for the users:
switch (using) {
case "class name":
toReturn.put("using", "css selector");
toReturn.put("value", "." + cssEscape(value));
break;
case "id":
toReturn.put("using", "css selector");
toReturn.put("value", "#" + cssEscape(value));
break;
case "link text":
// Do nothing
break;
case "name":
toReturn.put("using", "css selector");
toReturn.put("value", "*[name='" + value + "']");
break;
case "partial link text":
// Do nothing
break;
case "tag name":
toReturn.put("using", "css selector");
toReturn.put("value", cssEscape(value));
break;
case "xpath":
// Do nothing
break;
}
return toReturn;
Which locator strategies can be used to find the element in selenium for the below code
As per the HTML you can use only the following Locator Strategies:
LinkText:
Yearbooks
Xpath:
"//a[@class='collapsed noRewrite' and contains(@data-target, 'menu-yearbooks')]"
Viable locator strategies for partial link text in webdriver
Your question
Is visibility of element located a sub-par choice for partial link
text?
No, absolutely no.
See what is underneath of visibility_of_element_located
Method :-
""" An expectation for checking that an element is present on the DOM of a
page and visible. Visibility means that the element is not only displayed
but also has a height and width that is greater than 0.
locator - used to find the element
returns the WebElement once it is located and visible
"""
class visibility_of_element_located(object):
def __init__(self, locator):
self.locator = locator
def __call__(self, driver):
try:
return _element_if_visible(_find_element(driver, self.locator))
except StaleElementReferenceException:
return False
so basically it calls,
_element_if_visible
and this is what we have
def _element_if_visible(element, visibility=True):
return element if element.is_displayed() == visibility else False
So, direct answer to your question is No. But it depends, how you have defined EC, in your case, Are you sure if that is the unique link_text
or partial_link_text
,
did you try changing that to css or xpath and verified like below ?
//*[contains(text(),'Hello')]
in code :
msg_receive_1 = WebDriverWait(driver1, 15).until(
EC.visibility_of_element_located((By.XPATH, "//*[contains(text(),'Hello')]"))
)
as an xpath ?
How to find elements on gipfy.com using Selenium Webdriver
The locator strategy you have used:
/html/body/div[4]/div[1]/div/div[6]/div[2]/div[1]
identifies only one element within the HTML DOM, hence you see only a single element.
To extract the value of the href
attributes you have to induce WebDriverWait for visibility_of_all_elements_located() and you can use either of the following locator strategies:
Using XPATH:
driver.get("https://giphy.com/search/pixelart")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Agree and close']"))).click()
print([my_elem.get_attribute("href") for my_elem in WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//picture//ancestor::a[1][@href]")))])Console Output:
['https://giphy.com/gifs/party-epic-fest-26AHzeyITON4vzMM8', 'https://giphy.com/gifs/2tTh7wB6DtL1QQvAF5', 'https://giphy.com/gifs/perfect-loops-pVGsAWjzvXcZW4ZBTE', 'https://giphy.com/gifs/bw-pixelart-minimalism-3oEdvc7q2VwJFEQDGU', 'https://giphy.com/gifs/hoppip-heart-hoppip-pixel-BXVRf5GyMlElO', 'https://giphy.com/gifs/1yld7nW3oQ2IyRubUm', 'https://giphy.com/gifs/breakfast-bacon-egg-3oEdv9R4D62GPrVY4g', 'https://giphy.com/gifs/80s-synthwave-aesthetic-84SFZf1BKgzeny1WxQ', 'https://giphy.com/gifs/hoppip-heart-hoppip-pixel-1S9kD6xm4601O', 'https://giphy.com/gifs/xWMPYx55WNhX136T0V', 'https://giphy.com/gifs/perfect-loops-9LZTcawH3mc8V2oUqk', 'https://giphy.com/gifs/art-pixel-TRebCjNbc4dIA', 'https://giphy.com/gifs/80s-synthwave-aesthetic-k81NasbqkKA5HSyJxN', 'https://giphy.com/gifs/pixel-art-scenery-pI43YlhMoPqsE', 'https://giphy.com/gifs/pixel-sky-pixelart-2wh8ugh52dGSJYrA26', 'https://giphy.com/gifs/art-pixel-rzeWnbH8Uc5Y4', 'https://giphy.com/gifs/S5uMJDmtnATLbjjw3h', 'https://giphy.com/gifs/earth-spinning-globe-l3V0megwbBeETMgZa', 'https://giphy.com/gifs/pixel-netflix-art-26hisvCylQN7VcaOI', 'https://giphy.com/gifs/pixel-art-10GVNnqO2ZoAh2', 'https://giphy.com/gifs/art-pixel-marvel-NPd2pkbsjftS3O3U9c', 'https://giphy.com/gifs/OpCIhPH16jzsL3IzRp', 'https://giphy.com/gifs/animation-nes-pixelart-26tn84fF0eL3c898c', 'https://giphy.com/gifs/pixels-16bit-picel-art-3o85xunRezGKPOkcG4', 'https://giphy.com/gifs/pixel-art-octobit-pixeltober-l3vRgqJIdbRp7Exfa']
How to get the text from element in Selenium
Considering the HTML:
<td id="balance" class="ng-binding">$315.50</td>
To identify the element you can use either of the following locator strategies:
Using id:
@FindBy(how = How.ID, using = "balance")
private WebElement balance;Using cssSelector:
@FindBy(how = How.CSS, using = "td#balance")
private WebElement balance;Using xpath:
@FindBy(how = How.XPATH, using = "//td[@id='balance']")
private WebElement balance;
To print the text:
Using
getText()
:System.out.println(balance.getText())
Using
getAttribute("innerHTML")
:System.out.println(balance.getAttribute("innerHTML"))
Using
getAttribute("innerText")
:System.out.println(balance.getAttribute("innerText"))
Using
getAttribute("textContent")
:System.out.println(balance.getAttribute("textContent"))
Selenium findElement(By.CSS_SELECTOR)
The classnames i.e. sc-pjTqr
, dzmlqP
are dynamically generated and is bound to chage sooner/later. They may change next time you access the application afresh or even while next application startup. So can't be used in locators.
Solution
To identify the element with text as Continue you can use the following locator strategy:
Using xpath:
continue = driver.find_element(By.XPATH, "//button[text()='Continue']")
Ideally to identify the clickable element you need to induce WebDriverWait for the element_to_be_clickable() and you can use the following locator strategy:
Using XPATH:
continue = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[text()='Continue']")))
Note: You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Find items within <li> tags using Selenium
The locator strategies you have tried were a bit errorprone. The desired elements are within <li>
having class attribute as product-list detail
<div class='product'>
<div class='menuList1'> Menu1 Menu2</div>
<div class='menuList2'> aaa </div>
<ul id='productDetail' class='product-list'>
<li class='product-list detail' id='1'> Item1</li>
<li class='product-list detail' id='2'> Item2</li>
<li class='product-list detail' id='3'> Item3</li>
<li class='product-list detail' id='4'> Item4</li>
</ul>
</div>
Solution
To find the elements within the <li>
tags you can use either of the following locator strategies:
Using css_selector:
elms = driver.find_elements(By.CSS_SELECTOR, "div.product div.menuList2 > ul.product-list li.product-list.detail")
Using xpath:
elms = driver.find_elements(By.XPATH, "//div[@class='product']//div[@class='menuList2']/ul[@class='product-list']//li[@class='product-list detail']")
Related Topics
How to Fix Blurry Text in My Html5 Canvas
How to Use Sockets in JavaScript\Html
Cross-Origin Data in Html5 Canvas
Html Form Action and Onsubmit Issues
What Is Innerhtml on Input Elements
Pass Vars to JavaScript Via the Src Attribute
Ternary Operator in Angularjs Templates
Html "Overlay" Which Allows Clicks to Fall Through to Elements Behind It
Flask - Calling Python Function on Button Onclick Event
Relative Paths in JavaScript in an External File