My scenario is to make sure that my search bar is not sticky.
For this I am scrolling to middle of the page.
Now I need to check that my search bar is not visible in my viewport
.
isDisplayed
method is verifying for the element in whole page. so I cannot use this method.
-
Do you scrolling by code? in page?– Helping HandsCommented Jan 3, 2016 at 13:20
4 Answers
With JavaScript you can check if a DOM element is in the viewport, see this question for example code.
Now if we add this isElementInViewport()
JavaScript function to our application under test we can call it from Selenium with the JavaScriptExecutor and check its return value.
-
just an FYI this method only works in Firefox, chome and IE handle viewports differently so another solution might be required if that's functionality you need.– ECiurleoCommented Jan 4, 2016 at 16:21
-
Where do you read that? stackoverflow.com/a/7557433/1088584 states its tested on IE7+, iOS5+ Safari, Android2+, Blackberry, Opera Mobile, IE Mobile. Commented Jan 4, 2016 at 16:30
-
Also I would expect the jQuery inview to also work on all browsers: remysharp.com/2009/01/26/element-in-view-event-plugin Commented Jan 4, 2016 at 16:32
-
Usage may vary ofc, but I have had different behaviors between them (screenshots for example) because of how the browser handles it. Here is an article of viewport behavioral differences which isnt written by me, but highlights some of the differences quirksmode.org/mobile/tableViewport.html– ECiurleoCommented Jan 4, 2016 at 16:39
package First;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class isElementOnViewPort {
static ChromeDriver driver = new ChromeDriver();
public static void main(String arges[]) {
// System.setProperty("webdriver.gecko.driver",
// "/Users/vilas.kolhe/Downloads/geckodriver-v0.19.1-win64/geckodriver.exe");
// RemoteWebDriver driver = new ChromeDriver();
// WebDriver driver = new ChromeDriver();
driver.get("https://www.seleniumhq.org/download/");
driver.manage().window().maximize();
driver.manage().window().getSize();
boolean x = driver.findElement(By.xpath("//a[@title='Get Selenium']")).isDisplayed();
boolean y = driver.findElement(By.xpath("//img[@id='footerLogo']")).isDisplayed();
System.out.println("x- " + x+ " y- "+y);
isElementOnViewPort elementOnViewPort = new isElementOnViewPort();
elementOnViewPort.elementIsVisibleOnUI(driver.findElement(By.xpath("//a[@title='Get Selenium']")));
elementOnViewPort.elementIsVisibleOnUI(driver.findElement(By.xpath("//img[@id='footerLogo']")));
driver.quit();
// driver.get("https://www.seleniumhq.org/download/");
// String x = "success";
// String duplicateChars = "";
//
// for (int i = 0; i < x.length(); i++) {
//
// int j = x.split(x.charAt(i) + "").length;
//
// String arr[] = x.split(x.charAt(i) + "");
// if (j > 2) {
// duplicateChars = duplicateChars + x.charAt(i);
// }
// }
// System.out.println(duplicateChars);
}
public returnMulltipleValues fetchPosOfEleOnViewPort(WebElement webElement) {
// String x = "{top=2165, left=593, bottom=2180, width=27, right=620,
// height=15}";
// int topIndex = x.indexOf("top=");
// waitForPageLoaded();
// ChromeDriver driver = new ChromeDriver();
// Taking position of object on view point
Object posObject = ((JavascriptExecutor) driver).executeScript("return arguments[0].getBoundingClientRect();",
webElement);
// Converting it to string to fetch x,y, top, bottom of object
String position = posObject.toString();
//System.out.println(position);
int posFromTop = 0;
int posFfromLeft = 0;
int EquilsSignCount = 1;
for (int i = 0; i < position.length(); i++) {
String number = "";
if (position.charAt(i) == '=') {
for (int j = i; j < position.length(); j++) {
Character character = position.charAt(j);
// System.out.println("position.charAt(j) " + position.charAt(j));
if (character.isDigit(character)) {
number = number + position.charAt(j);
} else if (position.charAt(j) == ',' || position.charAt(j) == '.') {
break;
}
i = j;
}
if (number != "") {
if (EquilsSignCount == 1) {
posFromTop = Integer.parseInt(number);
} else if (EquilsSignCount == 2) {
posFfromLeft = Integer.parseInt(number);
} else if (EquilsSignCount >= 2) {
break;
}
EquilsSignCount++;
}
// Point x= driver.findElement(By.className("")).getLocation();
// x.getX();
// x.getY();
}
}
//System.out.println(posFromTop + "-" + posFfromLeft);
return new returnMulltipleValues(posFromTop, posFfromLeft);
}
public boolean elementIsVisibleOnUI(WebElement webElement) {
returnMulltipleValues returnMultipleValues= fetchPosOfEleOnViewPort(webElement);
int xCoorddinate =returnMultipleValues.getTopPos() ;
int yCoordinate = returnMultipleValues.getLeftPos();
Dimension Windowdimension = driver.manage().window().getSize();
if (xCoorddinate < Windowdimension.getHeight() && yCoordinate < Windowdimension.getWidth() && xCoorddinate>0 && yCoordinate>0) {
System.out.println("Visible");
return true;
}
System.out.println("Not visible");
return false;
}
// public boolean elementIsVisibleOnUI(WebElement webElement) {
// returnMultipleValues returnMultipleValues=
// fetchPosOfEleOnViewPort(webElement);
// int xCoorddinate =returnMultipleValues.getTop() ;
// int yCoordinate = returnMultipleValues.getLeft();
//
// Dimension Windowdimension = config.driver.manage().window().getSize();
// if (xCoorddinate < Windowdimension.getWidth() && yCoordinate <
// Windowdimension.getHeight() && xCoorddinate>0 && yCoordinate>0) {
// System.out.println("Visible");
// return true;
// }
// System.out.println("Not visible");
// return false;
// }
}
And,
package First;
public class returnMulltipleValues {
int topPos;
int leftPos;
//Parameterized constructor to return two values.
public returnMulltipleValues(int topPos, int leftPos) {
this.topPos = topPos;
this.leftPos = leftPos;
}
public int getTopPos() {
return topPos;
}
public int getLeftPos() {
return leftPos;
}
}
-
2For an old question like this, you should add an explanation of how your code will solve the original poster's question Commented Apr 19, 2017 at 11:23
-
Also, how will this code be useable if the element is within an iframe? Commented Oct 24, 2017 at 11:15
Webdriver.js example
This works where for example,
I do an action that scrolls the user to somewhere else on the page.
It checks that the upper left corner of the element that wasn't in the viewport before, now is in the viewport after the click or however you choose to use it.
I am not trying to make sure the element square fits perfectly in the viewport, I just need some reassurance that part of it is in the viewport and am reasonably sure so using the upper left corner of the element.
/* isElementInViewPort
* This function determines if the YOffset ot top of the element falls between the top of the
* client window and the bottom of the client window to determine if it's in the viewport.
* @param selector
* @return bool
*/
async isElementInViewPort(selector) {
// Get the needed element dimensions using webdriver
const elemLocation = await selector.getLocation();
const elemTopBoundY = await elemLocation.y;
// Get the needed client dimensions using javascript
const winUpperBound = await this.driver.executeScript('return window.pageYOffset');
const winHeight = await this.driver.executeScript('return document.documentElement.clientHeight');
const winLowerBound = winUpperBound + winHeight;
if (winUpperBound <= elemTopBoundY
&& winLowerBound >= elemTopBoundY) {
return true;
} return false;
}
/* waitForElementisinViewPort
* This function determines if the YOffset ot top of the element falls between the top of the
* client window and the bottom of the client window after an action such as a scroll.
* The wait avoids trying to do anything before the element is in the viewport.
* @param selector
* @state selector
* @param timeout
* @return bool
*/
async waitForElementToBeinViewPort(selector, state, timeout) {
try {
let isInViewpPort;
await this.driver.wait(async () => {
const bool = await this.isElementInViewPort(selector);
isInViewpPort = bool;
return bool === state;
}, timeout);
return isInViewpPort;
} catch (err) {
console.log(`Function: waitForElementToBeinViewPort failed ${err} `);
return null;
}
}
//A test example
const links = [{ link: 'All Web hosting deals', selector: coupons.selector.COUPON_DEALS_WEB },
{ link: 'Domain name deals', selector: coupons.selector.COUPON_DEALS_DOMAIN },
{ link: 'How do you redeem these coupons', selector: common.baseselector.FOOTER_CTA }];
describe('Coupons Page Extra Links section', () => {
links.forEach(async (link, i) => {
it('Click each Extra Links section link and verify an expected element is scrolled to', async () => {
await coupons.visit(page = '/coupons');
const nav = await driver.findElement(common.baseselector.mainNav);
// Need a scroll to top so that other tests don't leave the element under test off the page initially.
await driver.executeScript('arguments[0].scrollIntoView()', nav);
const linksToClick = await coupons.getExtraPlanLinks();
const element = await driver.findElement(links[i].selector);
await assert.isFalse(await coupons.waitForElementToBeinViewPort(element, false, timeout),
`element ${link.selector} should not be in the viewport`);
await linksToClick[i].click();
const bool = await coupons.waitForElementToBeinViewPort(element, true, timeout);
assert.isTrue(bool, ` element ${link.selector} should be in the viewport`);
});
});
});
public boolean isWebElementVisibleInViewPort(WebElement w) { Dimension weD = w.getSize(); Point weP = w.getLocation(); Dimension d = driver.manage().window().getSize();
int x = d.getWidth();
int y = d.getHeight();
int x2 = weD.getWidth() + weP.getX();
int y2 = weD.getHeight() + weP.getY();
return x2 <= x && y2 <= y && x2 >0 && y2 >0;
}