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

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 })

Related

Selenium XPATH selecting next sibling

<div class="block wbc">
<span></span>
<span> text_value </span>
</div>
for getting text in second span where does below code go wrong?
driver.find_element(X_PATH,"*//div[#class='block']/span[1]")
For trying by yourself, maybe I write sth wrong here is link
https://soundcloud.com/daydoseofhouse/snt-whats-wrong/s-jmbaiBDyQ0d?si=233b2f843a2c4a7c8afd6b9161369717&utm_source=clipboard&utm_medium=text&utm_campaign=social_sharing
And my code; still giving an error
playbackTimeline__duration =driver.find_element(By.XPATH,"*//div[#class='playbackTimeline__duration']/span[2]")
For finding web element clearly:
//*[#id="app"]/div[4]/section/div/div[3]/div[3]/div/div[3]/span[2]
But I will not use this way, I need declare with class method or CSS Selector at least
If you are sure that you always need the second span use this XPath:
*//div[#class='playbackTimeline__duration']/span[2]
If you need the first span that has actual text use this:
*//div[#class='playbackTimeline__duration']/span[normalize-space()][1]
If the #class has more than only playbackTimeline__duration in it you can use:
*//div[contains(#class,'playbackTimeline__duration')]/span[2]
If there are more div's like that use:
*//div[contains(#class,'playbackTimeline__duration')][1]/span[2]

How to match xpath for id element that changes each time page loads?

I have these 2 xpath that are different each time I load a webpage.
The xpaths were recorded by Selenium-IDE and always have mainForm_view within the id string and the text before and after this always changes.
xpath=//input[#id='abc_hyd_wuu2_8333nd_mainForm_view_jjd_uueue2_jjd_11_jkdhd']
xpath=//div[#id='abc_hyd_wuu2_8333nd_mainForm_view_kcjjcs_sjsjs_jjdj_994_kkk']/div/div[2]/div/div/div/a[1]/h2
I've tried to locate the id like below but doesn't work.
xpath=//input[contains(#id,'mainForm_view')]
xpath=//div[contains(#id,'mainForm_view')]
Which would be the correct way to do it?
Thanks in advance.
UPDATE
I've tried with CSS selector like below but it seems is taking another id that is within an input element
document.querySelector("input[id*='mainForm_view']").id
Examining the html code I see that the id I need is related with a unique class. The code is like below:
<div class="Class_p2">
<div class="Class_p3" style="...">
<input name="8333nd$mainForm$view$jjd$uueue2" type="text" class="class a1 n1-Control" value="xyz" id="8333nd_mainForm_view_jjd_uueue2" disabled="disabled" style="..">
</div>
<input name="8333nd$mainForm$view$ttyi" type="text" disabled="disabled">
</div>
I've tried the following Javascript code in Chrome console but it doesn't work
document.getElementsByClassName("class a1 n1-Control").id
How would be to get the id=8333nd_mainForm_view_jjd_uueue2 that is related with Class=class a1 n1-Control?
UPDATE2
I was finally able to do it with
document.getElementsByClassName("class a1 n1-Control")[0].id
Thanks for all the help and time.
You can write css selector as :
input[id*='mainForm_view']
for div it'd be :
div[id*='mainForm_view']
Asterisk is to match the sub string part.
Note that if any id contains mainForm_view that will also be selected, so better to check in developers tool before proceeding.
You can try finding some other element for which xpath/css locator remains same and then try to reach to this element by traversing from there. You can use parent, ancestor, preceding-sibling, following-sibling keywords in order to traverse. Hope it helps :)

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...."

Selenium wait for element to appear and dissapear

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")));

How to set the default value of input item with jQuery EasyUI framework

I am trying to set the default value of an input item from last two days.
For this, i have also searched in google but till not cannot find the solution.
I am using jQuery EasyUI framework.
<div class="fitem">
<tr>
<td></td>
<td>
<input type="text" class="easyui-validatebox" name="insertby" id="insertby" size="20">
</td>
</tr>
</div>
<script>
var s = '<?php echo $logname; ?>';
document.getElementById('insertby').value = s ;
alert(s);
</script>
As I am unable to add a comment to ask you to try stuff, I will try my best to help you out!
Firstly, your code works for me. However, there are times where other javascript codes causes errors and stops the code execution before your block of code. You might want to try pressing F12 on your Chrome browser to see if you encounter any errors before your block of code to ensure that all is well.
this code snip might have you
http://www.jeasyui.com/forum/index.php?topic=2623.0
$('#insertby').validatebox('setValue', s);
I took me while to "get it" too.
Actually, jquery easyUI modifies the DOM on the fly to make its fancy things in a way that the original input box is "gone" while you obtain their fancy widget instead. That's why modifying the input field directly has no effect, it is hidden actually. I guess this is done so because their getters/setters should be used in order to update everything correctly.
EasyUI is very easy to set up and play with, but it's way to operate on elements is rather unintuitive. But once you got the hang of it, it should be all right.
Use
setValue. $('idofcombogrid').('setValue',id_value);
The id_value refers to the value of idField as defined initially for the combogrid.