Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update waits.zh-cn.md translate to chinese #1561

Open
wants to merge 4 commits into
base: trunk
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 51 additions & 79 deletions website_and_docs/content/documentation/webdriver/waits.zh-cn.md
Original file line number Diff line number Diff line change
@@ -1,70 +1,47 @@
---
title: "等待"
linkTitle: "等待"
title: "等待策略"
linkTitle: "等待策略"
weight: 6
aliases: ["/documentation/zh-cn/webdriver/waits/"]
---

Perhaps the most common challenge for browser automation is ensuring
that the web application is in a state to execute a particular
Selenium command as desired. The processes often end up in
a _race condition_ where sometimes the browser gets into the right
state first (things work as intended) and sometimes the Selenium code
executes first (things do not work as intended). This is one of the
primary causes of _flaky tests_.

All navigation commands wait for a specific `readyState` value
based on the [page load strategy]({{< ref "drivers/options#pageloadstrategy" >}}) (the
default value to wait for is `"complete"`) before the driver returns control to the code.
The `readyState` only concerns itself with loading assets defined in the HTML,
but loaded JavaScript assets often result in changes to the site,
and elements that need to be interacted with may not yet be on the page
when the code is ready to execute the next Selenium command.

Similarly, in a lot of single page applications, elements get dynamically
added to a page or change visibility based on a click.
An element must be both present and
[displayed]({{< ref "elements/information/#is-displayed" >}}) on the page
in order for Selenium to interact with it.

Take this page for example: https://www.selenium.dev/selenium/web/dynamic.html
When the "Add a box!" button is clicked, a "div" element that does not exist is created.
When the "Reveal a new input" button is clicked, a hidden text field element is displayed.
In both cases the transition takes a couple seconds.
If the Selenium code is to click one of these buttons and interact with the resulting element,
it will do so before that element is ready and fail.

The first solution many people turn to is adding a sleep statement to
pause the code execution for a set period of time.
Because the code can't know exactly how long it needs to wait, this
can fail when it doesn't sleep long enough. Alternately, if the value is set too high
and a sleep statement is added in every place it is needed, the duration of
the session can become prohibitive.

Selenium provides two different mechanisms for synchronization that are better.


## Implicit waits
Selenium has a built-in way to automatically wait for elements called an _implicit wait_.
An implicit wait value can be set either with the [timeouts]({{< ref "drivers/options#timeouts" >}})
capability in the browser options, or with a driver method (as shown below).

This is a global setting that applies to every element location call for the entire session.
The default value is `0`, which means that if the element is not found, it will
immediately return an error. If an implicit wait is set, the driver will wait for the
duration of the provided value before returning the error. Note that as soon as the
element is located, the driver will return the element reference and the code will continue executing,
so a larger implicit wait value won't necessarily increase the duration of the session.

*Warning:*
Do not mix implicit and explicit waits.
Doing so can cause unpredictable wait times.
For example, setting an implicit wait of 10 seconds
and an explicit wait of 15 seconds
could cause a timeout to occur after 20 seconds.

Solving our example with an implicit wait looks like this:
浏览器自动处理最大的挑战可能是确保网页在某个确定的、期望的状态下执行 Selenium 命令。
这些过程通常处于 混乱竞争状态, 有时候网页先处理好,有时候 Selenium 命令先执行。
这就是为什么需要稳定性测试。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you keep the original style on flaky tests?


所有导航命令都需要一个准确的 `Ready状态` 值, 这取决于 [网页加载策略]({{< ref "drivers/options#pageloadstrategy" >}}) (一个默认的完成值),之后`浏览器 Driver`将控制权交回给代码进行处理。
这个 `Ready状态` 只关心在html 中定义的 css js 是否被加载,但 js 加载通常导致网页资源的变动,执行下一个 Selenium 命令时,网页元素在交互后可能还没有出现在网页中,。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The assets are not only including css and js, it might be more generally treating as resources.
refer: https://www.selenium.dev/documentation/webdriver/drivers/options/#pageloadstrategy

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what should i do. replace "drivers/options#pageloadstrategy" to "https://www.selenium.dev/documentation/webdriver/drivers/options/#pageloadstrategy" ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, Just mention that you translated the "assets" as "css js" , but actually, that's not meaning of them only...


类似地,在一个单网页中,元素根据点击会动态地添加到网页中或者显示/隐藏。
这个元素必须存在且被[显示]({{< ref "elements/information/#is-displayed" >}}) 在网页中以确保Selenium 能够正确操作它。

参考这个例子: https://www.selenium.dev/selenium/web/dynamic.html
当"Add a box" 这个按钮被点击时,"div" 这个元素当时还没有被创建。
当"Reveal a new input" 这个按钮被点击时,一个隐藏的 text 字段元素正常显示。
在这两个动作中发生变化用了几秒钟,如果此时Selenium命令去执行点击这其中的按钮并和预期显示的元素交互,
在元素加载(处理)完成之前将会失败。

大多数人想到的解决办法是添加一个 sleep 时间,暂停后续执行。
因为代码并不知道具体需要等待多久,当没有暂停足够久时,依旧会失败。最终这个值会被设置为很高,且需要在几乎每个动作之间添加,
整个处理过程就会变得非常缓慢。

Selenium 提供了两种方式,来帮助解决这些问题

## 隐形等待(自动等待) Implicit waits

Selenium 通过内建的机制自动等待元素被称为_隐形等待_。
这个隐形等待值可以设置在 浏览器选项中或者 Selenium Driver 方法中(如下)。

这是一个全局值,将会影响所有元素位置调用。
初始值为0, 这意味着元素没被找到,将会直接报错。如果该值被设置了,浏览器 Driver 将会等待一段时间后报错。
注意只要元素被找到了,浏览器 Driver 会返回元素定位且代码会继续执行。
所以设置一个很大的 Implicit 值并不会明显增加整个过程的操作时间。

*警告*
不要混淆 隐性和显性等待,这样做会导致预期之外的等待时间。
例如,同时设置10 秒Implicit 和 15秒的 Explicit 等待会在 20 秒后超时

使用 Implicit 解决我们的问题,如下:
{{< tabpane text=true >}}
{{< tab header="Java" >}}
{{< gh-codeblock path="examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L50" >}}
Expand All @@ -86,15 +63,12 @@ Solving our example with an implicit wait looks like this:
{{< /tab >}}
{{< /tabpane >}}

## Explicit waits
## 显性等待(精确条件等待)Explicit waits
Laurel-rao marked this conversation as resolved.
Show resolved Hide resolved

_Explicit waits_ are loops added to the code that poll the application
for a specific condition to evaluate as true before it exits the loop and
continues to the next command in the code. If the condition is not met before a designated timeout value,
the code will give a timeout error. Since there are many ways for the application not to be in the desired state,
so explicit waits are a great choice to specify the exact condition to wait for
in each place it is needed.
Another nice feature is that, by default, the Selenium Wait class automatically waits for the designated element to exist.
_Explicit waits_ 使用循环等待应用中某个特定条件时生效,将会退出该循环继续执行命令
如果循环时间到了但条件未被触发,将会报错。
鉴于有许多可能会导致不能处于期望的状态,所以Explicit 等待是一个不错的选择,可以指定某个确定的条件去等待。
Explicit 另一个很好的方面是Selenium 能自动等待该元素出现。

{{< tabpane text=true >}}
{{% tab header="Java" %}}
Expand Down Expand Up @@ -122,19 +96,17 @@ JavaScript also supports [Expected Conditions]({{< ref "support_features/expecte
{{< /tab >}}
{{< /tabpane >}}

### Customization
### 自定义选项

The Wait class can be instantiated with various parameters that will change how the conditions are evaluated.
Explicit 等待类有几种参数能够使得该条件被如何执行

This can include:
* Changing how often the code is evaluated (polling interval)
* Specifying which exceptions should be handled automatically
* Changing the total timeout length
* Customizing the timeout message
包括以下方面:
* 修改间隔多久检查一次
* 指定哪种异常应该被自动处理
* 修改整体超时时间
* 自定义超时报错信息

For instance, if the _element not interactable_ error is retried by default, then we can
add an action on a method inside the code getting executed (we just need to
make sure that the code returns `true` when it is successful):
举个栗子, 如果 _element not interactable_(元素不能交互) 这个错误默认重试,我们可以在代码被执行时执行一个动作(假设这个动作是成功时返回 true)

{{< tabpane text=true >}}
{{% tab header="Java" %}}
Expand Down