Selenium java SafariDriver点击后等待页面加载

时间:2018-04-01 06:59:03

标签: selenium safaridriver

当我运行以下代码时,执行突然结束,除非我取消注释Thread.sleep()。结果我的撤销url servlet中的代码没有被执行。点击是一个提交按钮点击,它会加载另一个页面。

 <DataTemplate>
    <Border  Background="#f0f4f7">
        <StackPanel Background="#f5f6fa" Margin="1,1,1,1" VerticalAlignment="Top">
            <Border Background="#edf0f5" BorderThickness="5">
                <Grid  Background="#ffffff" Height="30">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <StackPanel Background="#ffffff" Margin="5" Orientation="Horizontal">
                        <Button Height="20" Width="20" BorderBrush="Transparent" BorderThickness="0" Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.DeleteCommand}">
                            <Button.Background>
                                <ImageBrush ImageSource="..\Resources\Delete.png"/>
                            </Button.Background>
                        </Button>
                        <Button Height="20" Width="20" BorderBrush="Transparent" BorderThickness="0" Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.EditCommand}">
                            <Button.Background>
                                <ImageBrush ImageSource="..\Resources\Edit.png"/>
                            </Button.Background>
                        </Button>
                    </StackPanel>
                    <TextBlock Name="txtPhon" Foreground="#7c7f84" HorizontalAlignment="Right" Grid.Column="1" Text="{Binding Path=HomePhoneNumber}"
    Margin="0,5,5,5"/>
                </Grid>
            </Border>
        </StackPanel>


    </Border>
</DataTemplate>

让硒等到页面加载的正确方法是什么?

我正在使用以下selenium版本

        EventFiringWebDriver webDriver = new EventFiringWebDriver(new SafariDriver());
        try {
            webDriver.get("http://localhost:9988");
            webDriver.findElement(By.id("amount")).sendKeys(new StringBuffer().append(amount.getRupees()).append('.').append(amount.getPaise()).toString());
            webDriver.findElement(By.id("withdraw")).click();
            //Thread.sleep(10000);
        } finally {
            webDriver.close();
        }

1 个答案:

答案 0 :(得分:0)

听起来像明确的等待可能是你需要的。 ExpectedConditions课程中有一系列即用条件(有关详情,请参阅https://www.seleniumhq.org/docs/04_webdriver_advanced.jsp)。但是一旦你理解了它们是如何工作的,那么制作你自己的工作非常简单。这些的美妙之处在于,与Thread.sleep()不同,一旦满足条件,它就会立即停止等待。

我写了一些我过去用来等待“页面加载”的具体例子,然后了解如何创建自己的例子以防万一它对你有用:

如果您的页面对ajax内容有所了解,并且只加载一些静态内容,则可以实现显式等待条件来检查DOM的readyState属性

// this could benefit being static so it doesn't create new classpath defs every invocation
public ExpectedCondition<Boolean> readyStateIsComplete() {

    return new ExpectedCondition<Boolean>() {
        @Override
        public Boolean apply(WebDriver webDriver) {
            String readyState = (String) ((JavascriptExecutor) webDriver)
                    .executeScript("return document.readyState");

            return readyState.equals("complete");
        }

        public String toString() {
            return "page document's readyState flag to be complete";
        }
    };
}

只有在完成所有静态内容加载后,此属性才会“完成”。使用它可能就像:

// prepare me like this
WebDriverWait wait = new WebDriverWait(driver, maxSecondsToWait);

// Use me like this
wait.until(readyStateIsComplete());

上述示例适用于首次在所有内容完成之前加载页面。如果您的页面对ajax内容很重,可能相反或者除此之外您可以尝试等待ajax队列达到零,这可以在已经加载的页面上完成,该页面具有正在执行的ajax工作。

public ExpectedCondition<Boolean> activeQueuesToFinish() {

    return new ExpectedCondition<Boolean>() {

        public Boolean apply(WebDriver driver) {

            // This is just a formatted javascript block with in-string indenting
            String jScript = "if (A4J.AJAX) {" +
                    "            with (A4J.AJAX) {" +
                    "                var queues = A4J.AJAX.EventQueue.getQueues();" +
                    "                    for (var queueNames in queues) {" +
                    "                        return A4J.AJAX.EventQueue.getQueue(queueNames).getSize() <= 0;" +
                    "                    }" +
                    "                }" +
                    "            }" +
                    "        return true;";
            try {
                return (Boolean) ((JavascriptExecutor) driver).executeScript(jScript);
            } catch (WebDriverException e) {
                return true;
            }
        }

        public String toString() {
            return "active queues to finish.";
        }
    };

如果你使用jquery,你可以试试这个让当前的ajax工作完成:

public ExpectedCondition<Boolean> allAjaxRequestsFinish() {
    return new ExpectedCondition<Boolean>() {
        public Boolean apply(WebDriver driver) {
            try {
                return (Boolean) ((JavascriptExecutor) driver).executeScript("return jQuery.active == 0");
            } catch (Exception e) {
                return true;
            }
        }

        public String toString() {
            return "all ajax requests to finish.";
        }
    };
}

您在此模板中创建的所有条件或条件都可以以相同的方式用于动态等待:

wait.until(activeQueuesToFinish());
wait.until(allAjaxRequestsFinish());

编辑:

“模板”我的意思是这种形式的函数:

public ExpectedCondition<Boolean> myCustomCondition(/* some arguments from the outside */) {
    return new ExpectedCondition<Boolean>() {
        public Boolean apply(WebDriver driver) {
            // Check something on the page and return either true or false,
            // this method will be run repeatedly until either the time
            // limit is exceeded, or true is returned
        }

        public String toString() {
            return "a description of what this is waiting for";
        }
    };
}

以下是一个示例,说明如何执行此操作以等待可能阻碍页面的特定元素:

public ExpectedCondition<Boolean> waitForElementToHaveText(final WebElement element, final String expectedText) {
    return new ExpectedCondition<Boolean>() {
        public Boolean apply(WebDriver driver) {
            try {
                return element.getText().equals(expectedText);
            } catch (Exception e) {
                return false; // catchall fail case
            }
        }

        public String toString() {
            return "an element to have specific text";
        }
    };
}