Selenium wait for element to appear and dissapear - selenium

I have the following element:
<div class="ui-helper-hidden" id="shell.indicator.busy">
<label>Processing...</label>
<br />
<img src="/RightCrowd/Images/loading.gif" alt="" />
</div>
And it appears like this:
I would like to wait for it to appear and then to disappear and continue with accessing elements. This appears on most pages of the web application. We've tried a few things but sometimes it is visible by Selenium and sometimes is not, although I can see it with my eyes.
I believe that this processing image appears on top of the current page and using the current handler may be useless. Not sure.
We've tried something like this:
WebElement element = (new WebDriverWait(webDriver, 10))
.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//img[contains(#src,'/Images/loading.gif')]")));
boolean processingEnd = (new WebDriverWait(webDriver, timeoutWaitForProgressbar))
.until(ExpectedConditions.invisibilityOfElementLocated(By.id("shell.indicator.busy")));
So we've tried both xpath and id... Please let me know what's the best way to handle this situation.

By default, the WebDriverWait would check the Expected Condition status every half a second. I would try to issue the expected condition check requests more often with a FluentWait class:
Wait wait = new FluentWait(driver)
.withTimeout(timeoutWaitForProgressbar, SECONDS)
.pollingEvery(100, MILLISECONDS);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("shell.indicator.busy")));

Related

Testcafe - Selecting checkbox using id always end up with the full timeout wait

Our html codes for checkbox always look something like this
<div id="paymentCheckBoxesMod" class="c-form__checkbox-container u-spacing__margin-bottom--16 u-spacing__margin-top--16">
<input type="checkbox" id="supplementaryAgreement" aria-describedby="paymentsCheckboxLabel">
<label for="supplementaryAgreement">
</label>
<div id="paymentsCheckboxLabel">
Jag godkänner Storytels <span id="purchasetermspopup">Köpvillkor</span> & <span id="privacypolicypopup">Integritetspolicy</span>
</div>
</div>
ive always located the element using the label's for="supplementaryAgreement" because if i use the input's id="supplementaryAgreement"i end up having to wait for the timeout duration before the element is located. Does anyone know why?
so that has worked fine until i have to work for iframes and although ive already switched back to mainframe however i will get the error that there is no match on the DOM tree if i use for="supplementaryAgreement" now. It still work with id="supplementaryAgreement" but having to wait for it to timeout doesn't seem efficient.
I think that the cause of this issue is in the complex markup of your checkbox. It seems that the checkbox is overlapped by the label::after element, so TestCafe cannot correctly find the checkbox. The other issue is that label[for=supplementaryAgreement] has height equal to 0.
Your idea with decreasing the timeout for the selector is a good workaround in this case. It does not work since there is a syntax mistake. Please try the following approach: Selector('#supplementaryAgreement', { timeout: 1000 })

Selenium cannot find element by ID nor xpath

I'm trying to write a script in python (3.7.3) to automate logging into a website by using Selenium for the first time. I practiced with some basic examples and went through the Selenium documentations. All good so far. But when I try it on a website of my own choice; things go wrong...
I'm managing to open up the login page, but whenever I try to get the element ID corresponding to the username field, I'm getting the "NoSuchElementException", indicating that the ID-name I'm using is supposedly incorrect. I'm getting the name by looking at the HTML code by right clicking in the username-box and using the inspect function. When this is not working, I'm trying to find it through xpath, but also without success. Can anyone point out why the element is not being recognized?
Python code
from selenium import webdriver
path = r"C:\Users\path\chromedriver.exe"
driver = webdriver.Chrome(path)
driver.get ("https://a website")
driver.find_element_by_id("login-username").send_keys(login)
driver.find_element_by_id("login-sign-in-button").click()
Error message
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[id="login-username"]"}
HTML code of the username field:
<input id="login-username" type="text" name="username" placeholder="Username" msd-placeholder="Username" class="margin-bottom form-control ng-pristine ng-empty ng-invalid ng-invalid-required ng-touched" ng-model="formData.username" dh-autofocus="" required="">
Looking for element with xpath. I've changed the "" brackets around the id by '' to avoid errors.
driver.find_element_by_xpath("//*[#id='login-username']").send_keys(login)
And finally I tried the long xpath
driver.find_element_by_xpath("/html/body/ui-view/ui-view/div/div[1]/div[1]/ui-view/div/div[1]/div/div[2]/form/div[1]/div/input").send_keys(login)
I'm honestly hitting a brick wall here. It's probably not helping my knowledge of HTML is practically non existing.
EDIT 1
Added wait function. Code works now
driver.get ("https://a website")
element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "login-username")))
driver.find_element_by_id("login-username").send_keys(login)
Answering to close this question.
As Alok pointed out, we need to wait for the webelement to get loaded completely before trying to access it.
driver.get ("https://a website")
element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "login-username")))
driver.find_element_by_id("login-username").send_keys(login)

Protractor - "More than one element found for locator" when using by.id

We are using by.id to reference an element but Protractor is still throwing this message "more than one element found for locator By(css selector, *[id="txt1"])" and it is returning the value of a label when getText() is used. The behaviour seems strange. When we refer to that element from Javascript, the reference seems fine. Appreciate your help in resolving this.
//Code in Protractor, it seems to be referring to a label
var txtEl=element(by.id('txt1'));
//Code in VueJS, where the ID is set to each InputText
//This is the label
<label class="form__label" v-model="form.label" v-show="form.hasOwnProperty('label')">
{{ index }}. {{ form.label }}
</label>
<el-input type="text"
:id="currentField.id"
:placeholder="currentField.isPlaceholderVisible ? currentField.placeholder : ''"
v-model="currentField.value">
</el-input>
//Code in Javascript, works fine, shows the right value
console.log("Value:" + this.$refs.form1["txt1"].value);
Try printing the source code at this time and you will fine out how many elements are in DOM with similar id
Try this one
element(by.css('input[type = "text"]'))
Finally found the answer after frustrating 10 hours of digging through.
Set ":name" for . Don't set ":id". Like this :name="currentField.id"
In Protractor code, use the name to fetch the element. Like this -
var inputtxt=element(by.css("input[name='txt1']"));
Don't use getText(), it behaves weird, return empty. Use inputtxt.getAttribute('value')) where "value" is the underlying field assigned to "v-model"
IMPORTANT - allow the page to load fully by setting browser.sleep(x ms). Else the element gets retrieved multiple times, protractor throws a warning "More than one element is located...."

Handle elements that have changing ids all the time through Selenium Webdriver

I am running the script to automate test cases and having this unique problem.
I have detected and used IDs of the elements for click etc. purpose. However, all of a sudden these ids have changed and the script works no more.
Another weird thing is those IDs are same as in script when inspected in Chrome but different in Firefox driver browser.
Firebug for test driver: -
<p class="description" onclick="selectElementTextListForIE(this,'tile29', 'tile19');selectElementTextList(this,'tile29', '')" id="tile29_span_0_0">
Platinum
</p>
Chrome inspector for same element: -
<p class="description" onclick="selectElementTextListForIE(this,'tile20', 'tile19');selectElementTextList(this,'tile20', '')" id="tile20_span_0_0">
Platinum
</p>
Also, what could be the best strategy for detecting such elements whose IDs are generated on run.
I even tried using XPATH but that too contains id's reference
eg. #id="tile276_input
Any help will be appreciated.
Thanks.
Abhishek
You can utilize CSS for this. For your element, looks like its:
<* id="tile276_input" />
What you need to do is find out what is changing about it. I assume it's the number inbetween. If it is, then your selector would look something like:
By.cssSelector("*[id^='tile'][id$='input']")
This will look for anything that has an ID that "starts with tile" and "ends with input. In our case, "tile276_input" matches that.
See this article if you want more information
You also can try contains and starts-with() for such things
driver.findElement(By.xpath("//*[contains(#id,'title')]"))
or
driver.findElement(By.xpath("//* [start-with(#id,'title')]"))
WebElement element = driver.getElement(By.cssSelector("[id^='title']);
Or
WebElement element = driver.getElement(By.cssSelector("id:contains('title')"));
You Can use this element to do desired actions.

Selenium webdriver testng, how to select this xpath/id

I am trying to find the correct Xpath in order to select the link of the HTML code below. I tried with id and also trying to catch the text with xpath but it doesn't work, I would appreciate some help.
<td>
<a id="2018" onclick="goToOperator(50210, 129216, 195481);">
<img src="/NexxarUtilWeb/images/logo/SWFS_lcc_small.jpg" alt="Logo">
<br>
2018 - LCC TRANS-SENDING LIMITED
</br>
</a>
</td>
Thank u in advance!
The correct locator would be:
WebElement myLink = driver.findElement(By.id("2018"));
If you really want to use an XPath you could use:
WebElement myLink = driver.findElement(By.xpath("//a[#id='2018']"));
Where the XPath is:
//a[#id='2018']
I suspect your real problem is that the element does not exist on the page when it is initially loaded but appears after a set amount of time, if that is your problem you want to use an explicit wait like this:
WebDriverWait waiting = new WebDriverWait(driver, 10, 100);
waiting.until(ExpectedConditions.visibilityOfElementLocated(By.id("2018"));
Of course you may not care about it being visible, you may just want it to be present:
WebDriverWait waiting = new WebDriverWait(driver, 10, 100);
waiting.until(ExpectedConditions.presenceOfElementLocated(By.id("2018"));
If none of this is helpful we are going to need some more detailed information from you about your problem, a stack trace showing the error you are getting would be useful as well.
In the above case we cant find the element by id(id is dynamically changing)
so, you can use tag name
options=driver.find_element_by_tag_name("br")
for option in options:
if("2018 - LCC TRANS-SENDING LIMITED" in option.text)
option.click()