Selenium not recognising checkbox with complex attribute - c#

I have the following checkbox on the webapp I am creating selenium scripts for.
The problem I am running into is that my script can't find this checkbox.
My code:
WebDriverWait wait = new WebDriverWait(SELENIUMWebDriver.Driver, TimeSpan.FromSeconds(30));
wait.Until(ExpectedConditions.ElementIsVisible(
By.XPath("input[#ng-model=\"model['attributes']['3']['attributes']['38'].value\"]"))).Click();
<div class="checkbox" ng-class="{ disabled: form.schema.isDisabled }">
<label>
<input type="checkbox" ng-disabled="form.schema.isDisabled" ng-change="form.onChange(model['attributes']['3']['attributes']['38'].value, form)" ng-model="model['attributes']['3']['attributes']['38'].value" ng-model-options="::form.ngModelOptions" ng-true-value="::'True'" ng-false-value="::'False'" class="ng-pristine ng-untouched ng-valid ng-empty">
<span class="checkbox-label ng-binding" ng-bind="form.title">Registratie EVR/SFH?</span>
</label>
<div class="help-block ng-binding ng-hide" ng-show="::form.description" ng-bind-html="form.description"></div>
</div>
What am I doing wrong?

If you have many checkbox with same className try the following using index
By.XPath("//input[#class='ng-pristine ng-untouched ng-valid ng-empty'][#type='checkbox'][1]");
Updated
By.XPath("//span[contains(text(),'Registratie')]/preceding-sibling::input[#class='ng-pristine ng-untouched ng-valid ng-empty'][#type='checkbox']");

Could you just use this xpath?
//span[contains(text(), 'Registratie EVR/SFH?')]/preceding-sibling::input
I saw that this value can change languages also. If that is the case you could add an "or" into your xpath so either would be acceptable.

Related

How to get an element where the attribute by which I select it can change in Selenium Webdriver C#?

I want to get the src attribute of some elements like this:
<div class="product-tile restored" data-v-27bc931c=""><a href="/p/apple-iphone-11-pro/R1NFM0000000T7"
class="product-tile__link">
<div class="product-tile__image product-img-front">
<img alt="Apple iPhone 11 Pro"
data-src="/img?width=300&height=300&action=resize&url=/catalog/product/6/f/6f7466aef1ae14ee4fe9764531ef69a1.jpg"
src="/img?width=300&height=300&action=resize&url=/catalog/product/6/f/6f7466aef1ae14ee4fe9764531ef69a1.jpg"
lazy="loaded">
<div class="image-loading"></div>
<!---->
</div>
<div class="product-tile__description">
<div title=" iPhone 11 Pro" class="product-tile__name"><span class="product-tile__brand">Apple</span> iPhone
11 Pro
</div>
<!---->
</div>
<div class="product-tile__footer">
<div class="product-tile__condition">
<div>Various conditions<span class="colors"><span class="dot">•</span>4 Colors</span></div>
</div>
<div class="product-tile__price">
<div class="price" data-v-678b2a80="">
<div class="current-price" data-v-678b2a80="">
<div class="from" data-v-678b2a80="">from</div>
<div data-testid="productPrice" class="amount" data-v-678b2a80="">
$647.00
</div>
</div>
<div data-v-678b2a80=""><span class="amount amount--del" data-v-678b2a80="">$1049.00</span> <span
class="amount amount--save" data-v-678b2a80="">Save
$402.00</span></div>
</div>
</div>
</div>
<div class="product-tile__loading"></div>
</a>
<!---->
</div>
I'm using driver.FindElement(By.CssSelector("img[lazy='loaded")) but the problem is that this attribute can also be loading. When I try driver.FindElement(By.TagName("img")) that doesn't work.
I don't want to use Try and Catch. How to can I get the src? Here is the website that i want to scrape
To consider both the cases, when value of lazy attribute is loaded and loading, you can use comma seperated values for the css-selectors and use the following locator strategy:
driver.FindElement(By.CssSelector("img[lazy='loaded'], img[lazy='loading']"))
References
You can find a couple of relevant detailed discussions in:
Any built-in way for branching waits with OR conditions?
WebDriverWait for multiple conditions (OR logical evaluation)
selenium two xpath tests in one

How do I check checkboxes on a page using IWebDriver in selenium C#?

I need to select multiple checkbox to Submit the form and the following code response in HTML format.
Here i have 4 check box. when i have launch the browser then first 3 checkbox is always checked and last one always Unchecked. Now i want first 3 checkbox should be uncheck and last one will be checked .how do i this with selenium c#
<div class="formSubSection">
<h4>
Details:</h4>
<div class="formField">
<div class="formFieldCheckBox">
<span title="Imported selector"><input id="aul00_ContentPlaceHolder1_aul02_chkVan" type="checkbox" name=aul00$ContentPlaceHolder1$ctl02$chkVan" checked="checked"><label for="aul00_ContentPlaceHolder1_ctl02_chkVan"> Is the Helpdesk?</label></span>
</div>
</div>
<div class="formField">
<div class="formFieldCheckBox">
<span title="home selector"><input id="aul00_ContentPlaceHolder1_ctl02_chkHome" type="checkbox" name="aul00$ContentPlaceHolder1$ctl02$chkHome" checked="checked"><label for="ctl00_ContentPlaceHolder1_aul02_chkMotorHome"> home?</label></span>
</div>
</div>
<div class="formField">
<div class="formFieldCheckBox">
<span title="Imported selector"><input id="aul00_ContentPlaceHolder1_ctl02_chkHorseBox" type="checkbox" name="aul00$ContentPlaceHolder1$aul02$chkHorseBox" checked="checked"><label for="aul00_ContentPlaceHolder1_aul02_chkHorseBox"> Is the vehicle?</label></span>
</div>
</div>
<div class="formField">
<div class="formFieldCheckBox">
<span title="car selector"><input id="aul00_ContentPlaceHolder1_aul02_chkCar" type="checkbox" name="aul00$ContentPlaceHolder1$ctl02$chkCar" checked="checked"><label for="ctl00_ContentPlaceHolder1_aul02_chkCar"> Is the Driver?</label></span>
</div>
</div>
</div>
It depends are you web elements have dynamical id and names.
I wold suggest solution to get all 4 elements (according to your post, I do not know rest of the DOM) and just to iterate trought the for loop. Something like
for(int i=0;i<driver.findElements(By.Class("formFieldCheckBox"));i++)
{
if(i>=5)
{
if(!driver.findElements(By.Class("formFieldCheckBox")).get(i).isSelected())
driver.findElements(By.Class("formFieldCheckBox")).get(i).click();
}
else
{
if(driver.findElements(By.Class("formFieldCheckBox")).get(i).isSelected())
driver.findElements(By.Class("formFieldCheckBox")).get(i).click();
}
}
This is the Java solution, but almost same code is for C#. Try it and let me know did it help.

Unable to perform click action on toggle button in selenium C#

While trying to automate my application, one of the webpage has three toggle button and i need to select the same.
Below the HTML code:
<div class="row">
<div class="col-md-12 ">
<label class="control-label dl-padding-top-5" for="consentToBureau">Do you give consent for Capitec to do a credit bureau enquiry?</label>
<span class="pull-right dl-padding-top-5">
<label class="dl-switch">
<input type="checkbox" checked="checked" value="false" name="consentToBureau" id="BureauConcentInput" required="" onchange="hideErrorById('BureauConcent')" class="dl-border-red">
<span class="dl-slider dl-round"></span>
</label>
</span>
<span class="col-md-12 dl-error-msg dl-top-border-red" id="BureauConcentError">Tick to accept the Bureau Concent</span>
</div>
</div>
<div class="row">
<div class="col-md-12">
<label class="control-label dl-padding-top-5" for="acceptTerms">Do you accept these terms of use?</label>
<span class="pull-right dl-padding-top-5">
<label class="dl-switch">
<input type="checkbox" checked="checked" name="acceptTerms" id="TermsAndConditionsInput" required="" onchange="hideErrorById('TermsAndConditions')" class="dl-border-red">
<span class="dl-slider dl-round"></span>
</label>
</span>
<span class="col-md-12 dl-error-msg dl-top-border-red" id="TermsAndConditionsError" style="">Tick to accept the term of use</span>
</div>
</div>
<div class="row">
<div class="col-md-12">
<label class="control-label dl-padding-top-5">Salary paid into Capitec account?</label>
<span class="pull-right dl-padding-top-5">
<label class="dl-switch">
<input type="checkbox" name="CapitecClient" id="isCapitecClientInput" required="" onchange="hideError(this)">
<span class="dl-slider dl-round"></span>
</label>
</span>
</div>
</div>
The click on the each toggle button lands on span class="pull-right dl-padding-top-5" but this class is similar for all three toggle buttons. But each toggle button has unique 'for' attribute and ID.
Below is the code tried but getting error as unable to locate element.
IWebElement Toggle = driver.FindElement(By.CssSelector("input[id='BureauConcentInput']>span[class='dl-slider dl-round']"));
Toggle.Click();
(or)
IWebElement Toggle = driver.FindElement(By.XPath("//*[#id='BureauConcentInput']/span"));
Toggle.Click();
Kindly suggest the right way to locate the element.
When you hover over the element in your browser tools, do you happen to see any visible/highlighted element? If not, that's the first indication that Selenium wouldn't be able to find it as well.
Your XPath was looking for a span child of the element with an id of "BureauConcentInput", however, the span was a sibling (e.g. it was in the same level of the document tree as the element). There are a few ways to getting to the span, but here are two:
//input[#id='BureauConcentInput']/..//span
//input[#id='BureauConcentInput']/following-sibling::span
Without necessarily seeing the page or knowing what UI framework the switches belong to (dl-slider), this answer would be my best guesstimate as the span doesn't seem to be a clickable element to me in its current state:
driver.FindElement(By.XPath("//input[#id='BureauConcentInput']/ancestor::span")).Click();
Update:
It appears as though your footer navbar at the bottom of the page is above the checkbox you want to select. You can attempt to scroll to the element first and then click. Check your window size - that could be an issue as well.
Here is an extension method for Scroll:
public static IWebElement Scroll(this IWebElement element)
{
IWebDriver driver = ((IWrapsDriver)element).WrappedDriver;
string script = "const elementRect = arguments[0].getBoundingClientRect();" +
"const absoluteElementTop = elementRect.top + window.pageYOffset;" +
"const middle = absoluteElementTop - (window.innerHeight / 2);" +
"window.scrollTo(0, middle);";
((IJavaScriptExecutor)driver).ExecuteScript(script, element);
return element;
}
You can use it right before Click() - e.g. driver.FindElement().Scroll().Click();
If that doesn't work, your next option would be to use the scrollIntoView() js method:
public static void ScrollIntoView(this IWebElement driver, string xpath)
{
((IJavaScriptExecutor)driver).ExecuteScript($"document.evaluate(\"{xpath}\", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.scrollIntoView()");
}
You will have to use this on a separate line - e.g. driver.ScrollIntoView("insert xpath here");
You could do something like the below.
driver.FindElement(By.Id("BureauConcentInput")).Click();
driver.FindElement(By.Id("isCapitecClientInput")).Click();
driver.FindElement(By.Id("TermsAndConditionsInput")).Click();
The one question I meant to ask you is, are the checkboxes all unchecked to begin with? If some are checked you you will want another method to determine the current state so that if you want to check the Terms and Conditions box, and it was already checked, you have no just unchecked it.

Cannot check a checkbox control using Selenium with C#

I'm trying to check a simple input type=checkbox using Selenium with C#, this is the HTML code I'm using:
<div _ngcontent-c5="" class="check-item">
<input _ngcontent-c5="" class="custom ng-untouched ng-pristine ng-valid" id="captcha" type="checkbox">
<label _ngcontent-c5="" for="captcha" translate="">Text</label>
</div>
I've tried almost all possible approaches like XPath, ID, Class name with no success, this seems to be an Angular label or something like that
Thanks in advance!
Have you tried By.CssSelector("[for='captcha']");? This is a css selector for labels that point to an input with an id.

Basic MVC: If-else logic in cshtml page

I am just learning MVC and I've created a form but I would like to set conditional formatting ... like with an if-else construct. I know this is basic, but can I put it on the form? If so, how do I code that? What I would like to do is gray out the background of a input box if the checkbox is NOT checked. Thanks in advance
<div class="left">
Emulate Access
</div>
<div class="right">
<input type="checkbox" name="Emulate" />
</div>
<div class="clear" />
<div class="left">
Emulate Associate:
</div>
<div class="right">
<input type="text" name="NmAssoc" />
</div>
I would use JQuery http://jquery.com/. It works great for this sort of thing.

Categories

Resources