简体   繁体   English

在 Selenium 中编写 Sleep 来加载页面中的元素?

[英]writing Sleep in Selenium to loading elements in page?

i wrote some codes for comparing prices from Website with a CSV file, my test works good but it takes long time (1 Minuet).我写了一些代码来比较网站和 CSV 文件的价格,我的测试效果很好,但需要很长时间(1 小步舞曲)。 I used Sleep before finding every elements in Webpage.在查找网页中的每个元素之前,我使用了 Sleep。 Do you have any other way to write this test that run codes faster, With this method it takes 1 second before loading every price and then comparing with prices in CSV file.On the other hand without sleep my code doesn't work because of loading page and finding elements.你有没有其他方法来编写这个运行代码更快的测试,使用这种方法需要 1 秒才能加载每个价格,然后与 CSV 文件中的价格进行比较。另一方面,如果没有睡眠,我的代码由于加载而无法工作页和查找元素。

public class TestBikeInsurancePrice extends HepsterTest {    
private void prepareTest() {
        initiateBrowserWebShop();
        var url = baseUrl + "/fahrradversicherung-test-2020";
        driver.get(url);
        handleCookie(driver);
    }

    @Test(priority = 1)
    void checkBeschädigung() throws FileNotFoundException {
        prepareTest();
        List<CsvPrice> stuff = readFromCSV("resources/price/Test Fahrradversicherung Upload.csv");

        stuff.forEach(csvPrice -> {
            System.out.println(csvPrice.getQualityName() + " " + csvPrice.getCoverageSum() + " " + csvPrice.getDurationTimeUnit() + " " + csvPrice.getDurationRiskPremium());
            Select price = new Select(driver.findElement(By.id("coverageSum")));
            price.selectByValue(csvPrice.getCoverageSum().toString());

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            String qualityName;
            if (csvPrice.getQualityName().equals("Diebstahl")) qualityName = "Nur Diebstahl";
            else qualityName = csvPrice.getQualityName();
            driver.findElement(By.xpath("//*[contains(text(),'" + qualityName + "')]")).click();

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            String duration;
            if (!csvPrice.getDurationTimeUnit().equals("MONTHS")) duration = "Preisvorteil";
            else duration = "flexibel, mtl. kündbar";
            driver.findElement(By.xpath("//*[contains(text(),'" + duration + "')]")).click();

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            WebElement priceElement = driver.findElement(By.xpath("//*[@id='product-configurator-spinner']//parent::span"));
            String priceAsString = priceElement.getText().split(" ")[0];
            System.out.println(priceAsString);
            Assert.assertEquals(csvPrice.getPriceBasePrice().setScale(2), new BigDecimal(priceAsString.replace(",", ".")).setScale(2));
        });
    }

Real Problem while using: Thread.sleep()使用时的实际问题: Thread.sleep()

Thread.sleep() is considered as the worst case of explicit wait because it has to wait for the full time specified as the argument of Thread.sleep(3000), before proceeding further. Thread.sleep() 被认为是显式等待的最坏情况,因为它必须等待指定为 Thread.sleep(3000) 参数的全部时间,然后才能继续进行。

As a result, the next step had to wait for the full time to get over.结果,下一步只得等满时才过去。

Solution: Change the Thread.sleep() into explicit wait .解决方案:将Thread.sleep()更改为explicit wait

In Selenium, in that situation "Waits" comes handy or play an important role in executing tests.在 Selenium 中,在这种情况下,“等待”会派上用场,或者在执行测试中发挥重要作用。

There are three type wait in Selenium. Selenium 有三种类型的等待。

  1. Implicit wait: In implicit wait, the WebDriver polls the DOM for a certain duration when trying to find any element.隐式等待:在隐式等待中,WebDriver 在尝试查找任何元素时会在一段时间内轮询 DOM。 This can be useful when certain elements on the webpage are not available immediately and need some time to load.当网页上的某些元素无法立即使用并且需要一些时间来加载时,这会很有用。

Code:代码:

WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
  1. Explicit wait Explicit waits allow our code to halt program execution, or freeze the thread, until the condition you pass it resolves.显式等待显式等待允许我们的代码停止程序执行或冻结线程,直到您传递给它的条件解决为止。 The condition is called with a certain frequency until the timeout of the wait is elapsed.以特定频率调用条件,直到等待超时结束。 This means that for as long as the condition returns a falsy value, it will keep trying and waiting.这意味着只要条件返回一个假值,它就会继续尝试和等待。

Code:代码:

WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("YOUR-LOCATOR")));
  1. FluentWait: FluentWait instance defines the maximum amount of time to wait for a condition, as well as the frequency with which to check the condition. FluentWait: FluentWait 实例定义了等待条件的最长时间,以及检查条件的频率。

Code:代码:

//Declare and initialise a fluent wait
FluentWait wait = new FluentWait(driver);
//Specify the timout of the wait
wait.withTimeout(5000, TimeUnit.MILLISECONDS);
//Sepcify polling time
wait.pollingEvery(250, TimeUnit.MILLISECONDS);
//Specify what exceptions to ignore
wait.ignoring(NoSuchElementException.class)

//This is how we specify the condition to wait on.
//This is what we will explore more in this chapter
wait.until(ExpectedConditions.alertIsPresent());

Ref:参考:

https://www.selenium.dev/documentation/en/webdriver/waits/ https://www.selenium.dev/documentation/en/webdriver/waits/

https://www.browserstack.com/guide/wait-commands-in-selenium-webdriver https://www.browserstack.com/guide/wait-commands-in-selenium-webdriver

Explicit wait: Explicit waits are available to Selenium clients for imperative, procedural languages.显式等待:对于命令式、过程语言,Selenium 客户端可以使用显式等待。 They allow your code to halt program execution, or freeze the thread, until the condition you pass it resolves.它们允许您的代码停止程序执行或冻结线程,直到您传递的条件解决为止。 The condition is called with a certain frequency until the timeout of the wait is elapsed.以特定频率调用条件,直到等待超时结束。 This means that for as long as the condition returns a falsy value, it will keep trying and waiting.这意味着只要条件返回一个假值,它就会继续尝试和等待。

I have added explicit wait to the code.我在代码中添加了显式等待。

WebDriverWait wait = new WebDriverWait(driver,10);
        
stuff.forEach(csvPrice -> {
            System.out.println(csvPrice.getQualityName() + " " + csvPrice.getCoverageSum() + " " + csvPrice.getDurationTimeUnit() + " " + csvPrice.getDurationRiskPremium());
            wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("coverageSum")));
            Select price = new Select(driver.findElement(By.id("coverageSum")));
            price.selectByValue(csvPrice.getCoverageSum().toString());


            String qualityName;
            if (csvPrice.getQualityName().equals("Diebstahl")) qualityName = "Nur Diebstahl";
            else qualityName = csvPrice.getQualityName();
            wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[contains(text(),'" + qualityName + "')]")));
            driver.findElement(By.xpath("//*[contains(text(),'" + qualityName + "')]")).click();

            String duration;
            if (!csvPrice.getDurationTimeUnit().equals("MONTHS")) duration = "Preisvorteil";
            else duration = "flexibel, mtl. kündbar";
            wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[contains(text(),'" + duration + "')]")));
            driver.findElement(By.xpath("//*[contains(text(),'" + duration + "')]")).click();

            wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@id='product-configurator-spinner']//parent::span")));
            WebElement priceElement = driver.findElement(By.xpath("//*[@id='product-configurator-spinner']//parent::span"));
            String priceAsString = priceElement.getText().split(" ")[0];
            System.out.println(priceAsString);
            Assert.assertEquals(csvPrice.getPriceBasePrice().setScale(2), new BigDecimal(priceAsString.replace(",", ".")).setScale(2));
        });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM