Application of DOM locators in Selenium - selenium-webdriver

I understood DOM locators but I don't know how to apply and locate the elements using DOM locators. I automate using Selenium with java but in DOM we have to locate writing document.getElementById("id of the element"). Copying same thing in Java code gives me error. Does any Library needs to be imported to use DOM locators or something else ?

If you want to use document.getElementById function inside your Java Selenium tests you can go for JavaScriptExecutor.executeScript() method like:
WebElement element = (WebElement) driver.executeScript("return document.getElementById('id of the element');");
however much easier would be using WebDriver.findElement(By.Id)
WebElement element = driver.findElement(By.id("id of the element"));
it is less code, more clear, faster and you will be able to use Explicit Waits in case of testing AJAX applications
WebElement element = new WebDriverWait(driver,10)
.until(ExpectedConditions
.presenceOfElementLocated(By.id("id of the element")));

Related

How can I call a predefined Geb Page element using WebDriver?

I created a re-usable WebDriver method, but I can't for the life of me figure out how I can call a predefined Geb page CSS selector using WebDriver.
This method works, but I can't seem to call it using WebElement element:
static void WaitVisibilityOfElement(WebDriver driver, By cssSelector, int timeoutInSeconds) {
WebDriverWait Wait = new WebDriverWait(driver, timeoutInSeconds)
Wait.until(ExpectedConditions.visibilityOfElementLocated(cssSelector)).click()
}
This is the element I am trying to call, and I want to just be able to use the name of the element flipperCardOne, but if I do that it doesn't work.
flipperCardOne(wait:true) {$ (".flex-item:nth-child(5) .front > .w-100")}
Geb's selector results (the things returned from calls to $()) are called Navigators and are a wrapper around collections of Selenium's WebElements. Because Navigators can be created from more than just css selectors (you can chain multiple find() calls on them, you can base them off xpath expressions and you can filter contents of them by matching their text, just to give a number of examples) you cannot map one to one from a Navigator to a css selector. If your intention is to always wait for flipperCardOne to be visible before interacting with it then the idiomatic way to do that would be to use waitCondition content option:
flipperCardOne(wait:true, waitCondition: { it.displayed }) {$ (".flex-item:nth-child(5) .front > .w-100")}
Then you could just do flipperCardOne.click() and it would work.
And if you insist on using a method similar to what you listed in the question (and I'd argue that it's not the right thing to do) then you'd need something like:
static void WaitVisibilityOfElement(WebDriver driver, WebElement webElement, int timeoutInSeconds) {
WebDriverWait Wait = new WebDriverWait(driver, timeoutInSeconds)
Wait.until(ExpectedConditions.visibilityOf(webElement)).click()
}
and then call it like:
WaitVisibilityOfElement(browser.driver, flipperCardOne.singleElement, 5)

Check text in a DOM element using Protractor

Here’s what I’m trying to do while testing an Angular app with Protractor. I would like to get a certain element, which is somewhat like this:
<div class="someClass">
<p>{{textFromBoundModel}}</p>
</div>
then get its html, and check whether it contains the text that I expect it to have.
I tried to get this element first by the cssContainingText method, but it didn't quite work (not sure why; maybe because the text within the paragraph is produced dynamically). So now I’m getting this element using just the by.css locator. Next, I'm checking whether it contains the text I’m testing for:
// this is Cucumber.js
this.Then(/^Doing my step"$/, function(callback){
var el = element(by.css('.someClass'));
expect(el).to.contain("some interesting string");
callback();
});
});
but this doesn't work. Problem is, el is some kind of a locator object, and I can’t figure out how to get html of the element it found in order to test against this html. Tried .getText(), with no success.
Any suggestions?
Does:
expect(el.getText()).to.eventually.contain("some interesting string");
work?
I believe you need the .eventually to wait for a promise to resolve, and you need the .getText() to get at the content of the div.
See the chai-as-promised stuff at the head of the cucumber sample.
Try the below solution worked for me
Solution 1 :
expect(page.getTitleText()).toContain('my app is running!');
Solution 2 :
expect<any>(page.getTitleText()).toEqual('my app is running!');

How to wait for page load to complete in Chrome browser

What is the command in webdriver to wait for page to load fully before performing action on the page in CHROME browser?
PageLoadTimeOut is not waiting for the page load to complete in Chrome whereas it is working fine in firefox.
In Chrome, if webelement is there on the page, webdriver is performing the action on webelement while page is getting loaded. This is causing scripts to fail randomly with exception 'element is not clickable'.
Please let me know if there is any solution for this.
Thanks
You can use custom wait methods for an element to be enable or visible on the page.
For Example create a custom method isElementEnable using following code:
driver.findElement(locator).isEnabled();
Or use the following code to check if the element is visible on page:
driver.findElement(locator).isDisplayed();
pass your element locator as input parameter to the method.
Or Alternatively use implicit wait:
driver.manage().timeouts().implicitlyWait(number_of_seconds, TimeUnit.SECONDS);
Hope this will help.
You can use the JavaScriptExecuter.executeScript to get document.readyState,to compare it to complete,as a condition to WebDriverWait.Like this:
WebDriverWait wait = new ...;
wait.until(new ExpectedCondition<Boolean>(){
public Boolean apply(WebDriver driver) {
return (JavaScriptExecutor) driver).executeScript("return document.readyState").equals("complete");
}
});
Unfortunately, with Chrome if you have a alert on page,you will get a UnhandledAlertException.And this will not occur for Firefox
It's a really old question, but anyone having the same question might find this useful:
For chromedriver, it is best to use sleep method:
import time
# some of your code
time.sleep(2)
# here your program will wait for two seconds
# rest of your code
You can find an appropriate time span that will ensure your page loads and pass that time as parameter. But using too big time will make program slower.

is it possbile to locate an element created by javascript using webdriver?

In firebug, I used element inspector to locate an element, and then use the name of that element to locate the element in webdriver by function of findElementByName, but it complains it can't find that element. The element is transformed by javascript, as I can't find it using "view page source". So is it possible to locate such element in webdriver?
can you provide some more details at least the html?
What I am assuming that you have to wait until your javaScript finish loading. Use this
if your application use jQuery. And then find the element using attribute. In that case you have to be perfect with the selector.
Something like this should work I am thinking.
By.CssSelector("[type='checkbox']") //attribute = attribute value

can not click on none visible element

I'm trying to test my angularjs app with protractorjs. I have set up selenium and got the server and runner working. My issue is that when I run my test I get the ElementNotVisibleError. I know that the element I am trying to select is hidden until certain fields have been filled in and this is how I would like this to be kept.
My question is, are there any workarounds to the issue via a call to wait or sleep. I have tried many variations of wait and sleep but with no luck.
My test code is
it('navigates the user to the login page', function(){
ptor = protractor.getInstance();
ptor.get('http://localhost:2222/#/page');
ptor.findElement(protractor.By.input('input.type1')).sendKeys('one');
ptor.findElement(protractor.By.input('input.type2')).sendKeys('two');
ptor.findElement(protractor.By.input('input.type3')).sendKeys('three');
ptor.findElement(protractor.By.input('input.type4')).sendKeys('four');
ptor.findElement(protractor.By.input('input.type5')).sendKeys('five');
ptor.findElement(protractor.By.input('input.type6')).sendKeys('six');
ptor.sleep(5000);
ptor.findElement(protractor.By.id('clickableBtn')).click();//not visible until above fields populated
}, 1000000);
Message from protractor is
Message:
ElementNotVisibleError: element not visible
If the element is not visible until you have input in all of the fields, it is because of Javascript. You may have to kick off that Javascript by typing Tab or Enter after typing that last field:
ptor.findElement(protractor.By.input('input.type6')).sendKeys(Keys.Tab);
Using javascript I was able to click
var linkToClick = ptor.driver.findElement(protractor.By.id('clickableBtn'));
ptor.executeScript("arguments[0].click();", linkToClick );
yes, WebDriver allows you to execute javascript on elements directly so simply do a javascript .click. You would need to convert to your own language but here is how I did it using C#
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
js.ExecuteScript("arguments[0].click()", element);
Browser.WaitForPageLoad(driver);
I actually created an extender method so that I simply type element.InvisibleClick(driver) and it clicks on it for me. More on that can be found documented HERE.
You can always give it opacity:0
-moz-opacity: 0.00; opacity:.00; filter: alpha(opacity=00);
This should work for all browsers.

Resources