答案 0 :(得分:1)
调整大小到 667, 375
的窗口时,您看到的元素来自移动视图,并且位于不同的位置在DOM Tree中。因此,您需要使用其他Locator Strategy,如下所示:
代码块:
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.addArguments("start-maximized");
chromeOptions.addArguments("disable-infobars");
chromeOptions.addArguments("--disable-extensions");
WebDriver driver = new ChromeDriver(chromeOptions);
driver.get("https://sfo-demo.herokuapp.com/model-portfolio");
System.out.println("Elements in list with full screen:");
System.out.println(new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.cssSelector("ul.model-portfolio-navs.hidden-sm.hidden-xs a"))).stream().map(element->element.getAttribute("innerHTML")).collect(Collectors.toList()));
driver.manage().window().setSize(new Dimension(667, 375));
System.out.println("Elements in list with window resized:");
System.out.println(new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.cssSelector("ul.model-portfolio-navs.mobile.hidden-md.hidden-lg a"))).stream().map(element->element.getAttribute("innerHTML")).collect(Collectors.toList()));
控制台输出:
Elements in list with full screen:
[
3 Portfolio recommendations based on your preferences
,
15 other portfolio choices available
]
Elements in list with window resized:
[Recommended (3), Others (15)]
答案 1 :(得分:1)
调整窗口大小时,DOM元素会过时,您需要再执行一次WebDriver.findElements()函数来获取更新的元素。
您可以在两种情况下使用相同的XPath locator来实现兼容性。
示例代码:
ChromeDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://sfo-demo.herokuapp.com/model-portfolio");
List<String> textBeforeResize = driver.findElements(By.xpath("//a[@data-toggle='tab']"))
.stream()
.map(WebElement::getText)
.collect(Collectors.toList());
System.out.println("Before:");
textBeforeResize.forEach(System.out::println);
driver.manage().window().setSize(new Dimension(667, 375));
System.out.println("After:");
List<String> textAfterResize = driver.findElements(By.xpath("//a[@data-toggle='tab']"))
.stream()
.map(WebElement::getText)
.collect(Collectors.toList());
textAfterResize.forEach(System.out::println);
演示:
答案 2 :(得分:0)
同意以上两个答案。使用绝对xpath定位不同的元素位置:
package arun;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import webdriverFactoryPatternUsingSupplier.*;
public class Q56527756 {
WebDriver driver = DriverFactory.getDriver(DriverType.CHROME);
@Test
public void demo() throws InterruptedException {
driver.get("https://sfo-demo.herokuapp.com/model-portfolio");
clickableByXpath("//*[@id=\"page-top\"]/div[3]/div[1]/nav/div[1]/a/img", 5);
WebElement no1 = byXpath("//*[@id=\"page-top\"]/div[3]/section/div[2]/div[3]/ul[1]/li[1]/a");
WebElement no2 = byXpath("//*[@id=\"page-top\"]/div[3]/section/div[2]/div[3]/ul[1]/li[2]/a");
String firstElementFirstTry = no1.getText();
String secondElementFirstTry = no2.getText();
System.out.println(firstElementFirstTry);
System.out.println(secondElementFirstTry);
driver.manage().window().setSize(new Dimension(667, 375));
// there are elementes fitting to no1's and no'2 xpath, but those are not the same, have no text
// after resize your two elements are moved in 'ul' level
WebElement no3 = byXpath("//*[@id=\"page-top\"]/div[3]/section/div[2]/div[3]/ul[2]/li[1]/a");
WebElement no4 = byXpath("//*[@id=\"page-top\"]/div[3]/section/div[2]/div[3]/ul[2]/li[2]/a");
String firstElementSecondTry = no3.getText();
String secondElementSecondTry = no4.getText();
System.out.println(firstElementSecondTry);
System.out.println(secondElementSecondTry);
driver.close();
driver.quit();
}
// custom wait method
public WebDriverWait waitSec(WebDriver driver, int sec) {
return new WebDriverWait(driver, sec);
}
public WebElement byXpath(String xpath) {
WebElement element = driver.findElement(By.xpath(xpath));
return element;
}
public WebElement clickableByXpath(String xpath, int sec) {
WebElement element = waitSec(driver, sec).until(ExpectedConditions.elementToBeClickable(By.xpath(xpath)));
return element;
}
}
输出:
Starting ChromeDriver 74.0.3729.6 (255758eccf3d244491b8a1317aa76e1ce10d57e9-refs/branch-heads/3729@{#29}) on port 15890
Only local connections are allowed.
Please protect ports used by ChromeDriver and related test frameworks to prevent access by malicious code.
[1560178038.495][WARNING]: This version of ChromeDriver has not been tested with Chrome version 75.
Čer 10, 2019 4:47:19 ODP. org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: OSS
3 Portfolio recommendations based on your preferences
15 other portfolio choices available
Recommended (3)
Others (15)
还有工厂,如果您想自己尝试(只需编辑路径):
package webdriverFactoryPatternUsingSupplier;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.firefox.internal.ProfilesIni;
public class DriverFactory {
private static final Map<DriverType, Supplier<WebDriver>> driverMap = new HashMap<>();
public static String chromedriverPath = "C:\\Users\\pburgr\\Desktop\\selenium-tests\\GCH_driver\\chromedriver.exe";
public static String chromeProfilePath = "C:\\Users\\pburgr\\AppData\\Local\\Google\\Chrome\\User Data";
public static String geckodriverPath = "C:\\Users\\pburgr\\Desktop\\selenium-tests\\FF_driver_0_23\\geckodriver.exe";
public static WebDriver driver;
//chrome driver supplier
private static final Supplier<WebDriver> chromeDriverSupplier = () -> {
System.setProperty("webdriver.chrome.driver", chromedriverPath);
ChromeOptions options = new ChromeOptions();
options.addArguments("user-data-dir=" + chromeProfilePath);
driver = new ChromeDriver(options);
driver.manage().window().maximize();
System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
return driver;
};
//firefox driver supplier
private static final Supplier<WebDriver> firefoxDriverSupplier = () -> {
FirefoxOptions options = new FirefoxOptions();
ProfilesIni allProfiles = new ProfilesIni();
FirefoxProfile selenium_profile = allProfiles.getProfile("selenium_profile");
options.setProfile(selenium_profile);
options.setBinary("C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe");
System.setProperty("webdriver.gecko.driver", geckodriverPath);
driver = new FirefoxDriver(options);
driver.manage().window().maximize();
return driver;
};
//add more suppliers here
//add all the drivers into a map
static{
driverMap.put(DriverType.CHROME, chromeDriverSupplier);
driverMap.put(DriverType.FIREFOX, firefoxDriverSupplier);
}
//return a new driver from the map
public static final WebDriver getDriver(DriverType type){
return driverMap.get(type).get();
}
}
和枚举:
package webdriverFactoryPatternUsingSupplier;
public enum DriverType {
CHROME,
FIREFOX,
// SAFARI, not implemented
// IE; not implemented
}