Checking and unchecking of a checkbox using Selenium WebDriver.
I am using the page object pattern, so my code appears this way.
SelectCheckBox("Check"); OR SelectCheckBox("Uncheck");
[FindsBy(How = How.Id, Using = "payment_sameasdeliveryaddress")]
public IWebElement checkbox_Address = null;
public void SetCheckBox(string value)
{
//Console.Write("checkbox state: " + checkbox_Address.Selected);
if (value.ToLower().Equals("uncheck") && checkbox_Address.Selected)
{
checkbox_Address.Click();
}
else if (value.ToLower().Equals("check") && !checkbox_Address.Selected)
{
checkbox_Address.Click();
}
It has been years since I wrote any .NET, so the below may not even compile! But hopefully you get the idea.
// The individual elements should be declared private
private IWebElement payment_sameasdeliveryaddress;
// If you name it same as the source element
// ID, PageFactory will find it for you
// flag = true, means you want it checked
public void SelectCheckBox(Boolean check)
{
if (!check && payment_sameasdeliveryaddress.Selected) {
payment_sameasdeliveryaddress.Click();
}
else if (check && !payment_sameasdeliveryaddress.Selected) {
payment_sameasdeliveryaddress.Click();
}
The simplest way of checking a checkbox is checked or not by using the isSelected() method with an element. For example:
if(getCheckBox().isSelected()){
getCheckBox.click();
}
public WebElement getCheckBox(){
return driver.findElement(termsCheck);
}
This would also work:
// flag = true, means you want it checked
public void SelectCheckBox(Boolean check)
{
if (check ^ payment_sameasdeliveryaddress.Selected) {
payment_sameasdeliveryaddress.Click();
}
}
Sharing the snippet that's just implemented in the current project using Selenium WebDriver 3.9.1 and TestNG 6.14.
// Returns boolean value based on whether check-box is selected or not
Boolean chkBx1Sel = driver.findElement(By.xpath(elementXpath)).isSelected();
Case 1: Check a check-box
if(dataValofChkBx != null && dataValofChkBx.equalsIgnoreCase("Y"))
{
if(chkBx1Sel.toString() == "false") //i.e., checkbox is not already checked
{
driver.findElement(By.xpath(POP2GUIConstants.ggsnFwlfUpdChkBx)).click();
}
}
Case 2: Uncheck a check-box
if(dataValofChkBx != null && dataValofChkBx.equalsIgnoreCase("N"))
{
if(chkBx1Sel.toString() == "true") // I.e., checkbox is already checked
{
driver.findElement(By.xpath(POP2GUIConstants.ggsnFwlfUpdChkBx)).click();
}
}
Related
I need a method where I can change time to wait for a certain criteria as per my requirement in selenium
Below Code will, firstly it will check whether Element is available in back-end or not, if element is available in back-end then it will wait till element display.(if element is not available in back-end then also it will wait till element is in back-end)
public void E_WaitUntilElementDisplay() throws Exception
{
int i=1;
boolean eleche,eleche1 = false;
while(i<=1)
{
try{
eleche = driver.findElements(By.id("ABC")).size()!=0;
}catch(InvalidSelectorException ISExcep)
{
eleche = false;
}
if(eleche == true)
{
while(i<=1)
{
try{
eleche1=driver.findElement(By.id("ABC")).isDisplayed();
}catch(org.openqa.selenium.NoSuchElementException NSEE){
eleche1=false;
}
if(eleche1 == true)
{
i=2;
System.out.println("\nElement Displayed.");
}
else
{
i=1;
Thread.sleep(1500);
System.out.println("\nWaiting for element, to display.");
}
}
}
else
{
i=1;
Thread.sleep(1500);
System.out.println("\nWaiting for element, to display.");
}
}
}
I am working on a sample project as my learning process. So in my project I am having an IsActive field which is a radio button . It will give either true or false. So if Is Active is False I have to make some fields mandatory like Reason,Remarks etc.I tried so many things but nothing is working for me.I am not understanding what all things I have to modify and also the places where I should modify
. I am working on MVC and consider my knowledge is low. And I have to do it as model validation so custom data annotation is what I want. Any help will be appreciated.
I created a cs file like
public class IsActiveTrue : ValidationAttribute
{
public override bool IsValid(object value)
{
var item = (Pen)value;
if (item.IsActive == false)
{
if (item.ReportNo == null || item.Reason == null || item.Remarks == null)
{
return false;
}
else
{
return true;
}
}
else
{
return true;
}
}
}
and in model
[IsActiveTrue(ErrorMessageResourceType = typeof(Resources.Resource), ErrorMessageResourceName = "Requried")]
public string Remarks { get; set; }
I am having message in the resourcse but the code is not working. please let me know wheather i am even near to the solution.
I have a TableViewer in my Eclipse plugin.
When I was just using a regular label provider, my tooltips worked beautifully:
However, when I switched to have my LabelProvider implement IStyledLabelProvider, my tooltips went haywire:
Here is the code creating the StyledString
#Override
public StyledString getStyledText(final Object element) {
if( !(element instanceof MyInterface<?>) ) {
return null;
}
final String elemText = getColumnText(element, this.columnIndex);
final StyledString styledString = new StyledString(elemText == null ? "" : elemText);
if( !(element instanceof MyObject) ) {
return styledString;
}
final MyObject settingElement = (MyObject) element;
// grayed out text
if( settingElement.shouldBeGray() ) {
styledString.setStyle(0, elemText.length(), AdaptabilityStyles.GRAY_STYLER;
} else if( !settingElement.shouldBeBlue() ) {
styledString.setStyle(0, elemText.length(), AdaptabilityStyles.BLUE_STYLER);
}
return styledString;
}
And getTooltTipText()
#Override
public String getToolTipText(final Object element) {
return getColumnText(element, this.columnIndex);
}
What am I doing wrong?
As I was writing this question, I wanted to reference a bug report that I am familiar with that is related to tooltips. I looked at the bug report again and came across the following line:
For now, I simply try this :
ColumnViewerToolTipSupport.enableFor(commonViewer)
I wasn't calling that method when I created my viewer. When I tried that, my tooltips came back (though slightly different than they were before.
In my application during releases, I'm forced to change id to xpath or class name or tag. So I can't use any of the element selection methods like driver.findElement(By.id()).
In the next build I might have to use driver.findElement(By.xpath()) OR driver.findElement(By.name()) for the same element location. This means I will have to visit each and every class file I have written and modify By.id() to the respective selector.
Is there any way to avoid this by parametrising or some other way to resolve this issue?
Thanks in advance.
Had similar issue so came up with this generic method
public WebElement getElement(Identifier identifier, String expression) {
By byElement = null;
switch (identifier) {
case xpath: {
byElement = By.xpath(expression);
break;
}
case id: {
byElement = By.id(expression);
break;
}
case name: {
byElement = By.name(expression);
break;
}
case classname: {
byElement = By.className(expression);
break;
}
case linktext: {
byElement = By.linkText(expression);
break;
}
case paritallinktext: {
byElement = By.partialLinkText(expression);
break;
}
case tagname: {
byElement = By.tagName(expression);
break;
}
}
WebElement element = driver.findElement(byElement);
return element;
}
public static enum Identifier {
xpath, id, name, classname, paritallinktext, linktext, tagname
};
You can also use properties file to store values. Like
# login
login.username.identifier=xpath
login.username.expression=//input[#id='userNameText']
and in Java you can write
SeleniumUtil.getElement(prop.getProperty("login.username.identifier"), prop.getProperty("login.username.expression")).click();
So you will not need to change any Java code
You can also make use of key=value in your locators as a good practice which was seen in Selenium 1.0 and accordingly the selector will be selected.
So you can have a common getByLocator method that returns you with the By class object, example code
public By getByLocator(String locator) {
By by = null;
if (locator.startsWith("class=")) {
by = By.className(locator.replace("class=", "").trim());
} else if (locator.startsWith("css=")) {
by = By.cssSelector(locator.replace("css=","").trim());
} else if (locator.startsWith("link=")) {
by = By.linkText(locator.replace("link=", "").trim());
} else if (locator.startsWith("//") or locator.startsWith("/")) {
by = By.xpath(locator);
} else if (locator.startsWith("id=")) {
by = By.id(locator.replace("id=", ""));
} else {
by = By.name(locator.replace("name=", ""));
}
return by;
}
Here I made use of link=, css=, id= as some of factors to identify the locator type and accordingly I got the By locator object.
The usage of this would be something like below
List<WebElement> element = driver.findElements(getByLocator("css= input[type=input]"));
You have to work on your framework. Make it more generic. My code handles the problem. I have used key and value concept. In my .properties file, I have defind the object like
Test_login_user=id||username
Test_login_pass=className||passwd
after that my code get the value and spits it from ||. Here I have mention the type of locator if its BY id then id||username etc.
public By extractWebElement(String keyobject){
if(keyobject.startsWith("name_")){
currentWebElement = By.name(actualLocator);
}else if(keyobject.startsWith("xpath_")){
currentWebElement =By.xpath(actualLocator);
}else if(keyobject.startsWith("linkText_")){
currentWebElement =By.linkText(actualLocator);
}else if(keyobject.startsWith("id_")){
currentWebElement =By.id(actualLocator);
}else if(keyobject.startsWith("cssSelector_")){
currentWebElement =By.cssSelector(actualLocator);
}else if(keyobject.startsWith("tagName_")){
currentWebElement =By.tagName(actualLocator);
}
return currentWebElement;
}
public String extractActualLocator(String locatorInSheet ){
int underScoreIndex = locatorInSheet.indexOf('_');
return locatorInSheet.substring(underScoreIndex+1);
}
Now actual locator is in the "currentWebElement", we can use this in our methods. See how my keywords are written
public String enterTextt(By object,String data){
APP_LOGS.debug("Writing in text box");
try{
***driver.findElement(object).sendKeys(data);***
}catch(Exception e){
return Constants.KEYWORD_FAIL+" Unable to write "+e.getMessage();
}
return Constants.KEYWORD_PASS;
}
In Selenium 2 I want to ensure that an element on the page that the driver has loaded does not exist. I'm including my naive implementation here.
WebElement deleteLink = null;
try {
deleteLink = driver.findElement(By.className("commentEdit"));
} catch (NoSuchElementException e) {
}
assertTrue(deleteLink != null);
Is there a more elegant way that basically verifies to assert that NoSuchElementException was thrown?
If you are testing using junit and that is the only thing you are testing you could make the test expect an exception using
#Test (expected=NoSuchElementException.class)
public void someTest() {
driver.findElement(By.className("commentEdit"));
}
Or you could use the findElements method that returns an list of elements or an empty list if none are found (does not throw NoSuchElementException):
...
List<WebElement> deleteLinks = driver.findElements(By.className("commentEdit"));
assertTrue(deleteLinks.isEmpty());
...
or
....
assertTrue(driver.findElements(By.className("commentEdit")).isEmpty());
....
You can use this:
Boolean exist = driver.findElements(By.whatever(whatever)).size() == 0;
If it doesn't exist will return true.
I split out page classes so I don't have to define elements more than once. My nunit and mbunit test classes call those page classes. I haven't tried this out yet but this is how I'm thinking about doing it so I can use .exists() like I did with WatiN.
Extension Class:
public static class ExtensionMethods
{
public static IWebElement ElementById(this IWebDriver driver, string id)
{
IWebElement e = null;
try
{
e = driver.FindElement(By.Id(id));
}
catch (NoSuchElement){}
return e;
}
public static bool Exists(this IWebElement e)
{
if (e == null)
return false;
return true;
}
}
Page Class:
public IWebElement SaveButton { get { try { return driver.ElementById("ctl00_m_m_body_body_cp2_btnSave")); } }
Test Class:
MyPageClass myPageClass = new MyPageClass(driver);
if (myPageClass.SaveButton.Exists())
{
Console.WriteLine("element doesn't exist");
}
You can retrieve a list of elements by using driver.findElements("Your elements") and then search for the element. if the list doesn't contains the element you got yourself your desired behavior :)
If you're using the Javascript API, you can use WebElement.findElements(). This method will return a Promise with an array of found elements. You can check the length of the array to ensure no items were found.
driver.findElements(By.css('.selector')).then(function(elements) {
expect(elements.length).to.equal(0)
})
I'm using Chai assertion library inside the Promise's callback to expect a certain value.
Reference: https://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebElement.html
Best solution
protected boolean isElementPresent(WebElement el){
try{
el.isDisplayed();
return true;
}
catch(NoSuchElementException e){
return false;
}
}
public boolean exist(WebElement el){
try {
el.isDisplayed();
return true;
}catch (NoSuchElementException e){
return false;
}
}
if(exist(By.id("Locator details"))==false)
or
WebElement el= driver.findElementby(By.locator("locator details")
public boolean exists(WebElement el)
try{
if (el!=null){
if (el.isDisplayed()){
return true;
}
}
}catch (NoSuchElementException e){
return false;
}
}
Using webdriver find_element_xxx() will raise exception in my code and take us the waiting time of implicit/explicit webdriver wait.
I will go for DOM element check
webdriver.execute_script("return document.querySelector('your css class')")
p.s.
Also found similar discussion on our QA-main sister site here
For full check for visibility+existence
# check NOT visible the :aftermeet and :viewintro
# ! . . ! !offsetWidth to check visible in pure js ref. https://stackoverflow.com/a/20281623/248616
css='yourcss'; e=wd.execute_script(f"return document.querySelector('{css}').offsetWidth > 0") ; assert not e
# check NOT exists :viewintro
css='yourcss'; e=wd.execute_script(f"return document.querySelector('{css}')") ; assert not e
Use assertFalse :)
assertFalse(isElementPresent(By.className("commentEdit")));