当行为测试和字段具有相同名称时处理填充字段的最佳方法
Best way to handle filling fields when behat testing and fields have the same name
我有一个网站的登录页面,该网站包含三种类型的用户。用户单击 his/her 类型,然后会出现 un/pw 字段,具体取决于用户单击的类型。然而,在页面源代码中,所有三种形式都存在,但根据选择的类型,有两种形式被隐藏。我正在尝试编写一个 behat 测试来测试记录每种类型的用户。我的 behat 测试如下所示:
@javascript @core
Feature: Secure Login
As a User
I expect to be asked for my credentials
So that I can use the system securely
Background:
Given I am logged out
Scenario: Failed User1 Login
When I go to user1 interface
When I submit incorrect user1 credentials
Then I should stay logged out
And I should see "The username or password entered does not match our records."
Scenario: Successful User1 Login
When I go to user1 interface
When I submit correct user1 credentials
Then I should be logged in to user1 interface
Scenario: Failed User2 Login
When I go to user2 interface
When I submit incorrect user2 credentials
Then I should stay logged out
And I should see "The username or password entered does not match our records."
Scenario: Successful User2 Login
When I go to user2 interface
When I submit correct user2 credentials
Then I should be logged in to user2 interface
当我查看页面源代码时,这是我看到的表单内容:
<form id='user1' name='user1' method="post" role="form">
<input type="hidden" name="subsystem" value="user1"/>
<label for="un1" class="label">Username</label>
<div id="un_inst1"class="label_instruction"></div>
<input autocapitalize="off" id="un1" autocorrect="off" type="text" name="username" value="" style="margin-bottom: 10px" aria-describedby="un_inst1">
<label for="pw1" class="label">Password</label>
<div id="pw_inst1"class="label_instruction"></div>
<input type="password" id="pw1" name="password" style="margin-bottom: 10px;" aria-describedby="pw_inst1">
<div class="login_buttons">
<input type="submit" value="Go" class="btn_go input-submit">
<input type="reset" class="btn_reset input-reset" value="Reset">
<br/>
</div>
</form>
<form id='user2' name='user2' method="post" role="form">
<input type="hidden" name="subsystem" value="resident"/>
<div class="usr-login label">Resident Login</div>
<label for="un2" class="label">Username</label>
<div id="un_inst2"class="label_instruction"></div>
<input autocapitalize="off" autocorrect="off" type="text" id="un2" name="username" value="" style="margin-bottom: 10px" aria-describedby="un_inst2">
<label for="pw2" class="label">Password</label>
<div id="pw_inst2"class="label_instruction"></div>
<input type="password" id="pw2" name="password" style="margin-bottom: 10px;" aria-describedby="pw_inst2">
<div class="login_buttons">
<input type="submit" value="Go" class="btn_go input-submit">
<input type="reset" class="btn_reset input-reset" value="Reset">
<br/>
</div>
</form>
在我的 featurecontext 文件中,我有这些函数:
public function iSubmitIncorrectCredentials($interface)
{
$button ='Go';
return $this->login("tester" . time(), "bar", $button);
}
private function login($username, $password, $btn)
{
$this->fillField('username', $username);
$this->fillField('password', $password);
$this->pressButton($btn);
}
其中 $interface 用于 user1 或 user2。我遇到的问题是 user1 的测试通过了,但是当我进行 user2 测试时,我得到这个错误:
{"errorMessage":"Element is not currently interactable and may not be manipulated","request":{"headers":{"Accept":"application/json;charset=UTF-8","Content-Length":"36","Content-Type":"application/json;charset=UTF-8","Host":"127.0.0.1:8643"},"httpVersion":"1.1","method":"POST","post":"{\"value\":[\"tester1479232631\ue004\"]}","url":"/value","urlParsed":{"anchor":"","query":"","file":"value","directory":"/","path":"/value","relative":"/value","port":"","host":"","password":"","user":"","userInfo":"","authority":"","protocol":"","source":"/value","queryKey":{},"chunks":["value"]},"urlOriginal":"/session/ea0f7000-ab5c-11e6-acb9-5946ec8fdb06/element/:wdc:1479232631203/value"}} (WebDriver\Exception\InvalidElementState)
我认为正在发生的事情是 fillField() 试图找到用户名字段,但有两个,所以对于 user1,测试有效,但对于 user2,我得到错误。除了更改 un/pw 字段的名称外,我还想获得有关如何处理此问题的一些建议。
谢谢
您需要为每个表单设置不同的选择器。您可以通过几种方式做到这一点:
对于前两种方法,您需要使用另一种方法来填充元素并单击字段,因为您将使用 css 选择器。
例如:找到元素-> click() 找到元素-> setValue()
1) 使用不同的选择器为每种类型创建一个方法
loginWithUser1($username, $password){...}
loginWithUser2($username, $password){...}
loginWithUser3($username, $password){...}
您将需要对以下元素使用 css 选择器:
#user1 input[name=username]
#user1 input[name=password]
2) 使用相同的方法和 build/read 基于参数
的数组选择器
login($username, $password, $role)
{
}
3) 使用页面对象功能
此选项将使用与第二个选项相同的方法,但不是从数组中读取选择器,而是使用 getElement() 方法并在该对象上使用您需要的方法。请在此处查看示例 working with elements
我建议尝试最后一个选项,如果您不能尝试第二个选项。
Tip: Avoid passing parameters in the method that you don't need like $btn from your login method.The method should know about the button element, you need to pass data only.
我有一个网站的登录页面,该网站包含三种类型的用户。用户单击 his/her 类型,然后会出现 un/pw 字段,具体取决于用户单击的类型。然而,在页面源代码中,所有三种形式都存在,但根据选择的类型,有两种形式被隐藏。我正在尝试编写一个 behat 测试来测试记录每种类型的用户。我的 behat 测试如下所示:
@javascript @core
Feature: Secure Login
As a User
I expect to be asked for my credentials
So that I can use the system securely
Background:
Given I am logged out
Scenario: Failed User1 Login
When I go to user1 interface
When I submit incorrect user1 credentials
Then I should stay logged out
And I should see "The username or password entered does not match our records."
Scenario: Successful User1 Login
When I go to user1 interface
When I submit correct user1 credentials
Then I should be logged in to user1 interface
Scenario: Failed User2 Login
When I go to user2 interface
When I submit incorrect user2 credentials
Then I should stay logged out
And I should see "The username or password entered does not match our records."
Scenario: Successful User2 Login
When I go to user2 interface
When I submit correct user2 credentials
Then I should be logged in to user2 interface
当我查看页面源代码时,这是我看到的表单内容:
<form id='user1' name='user1' method="post" role="form">
<input type="hidden" name="subsystem" value="user1"/>
<label for="un1" class="label">Username</label>
<div id="un_inst1"class="label_instruction"></div>
<input autocapitalize="off" id="un1" autocorrect="off" type="text" name="username" value="" style="margin-bottom: 10px" aria-describedby="un_inst1">
<label for="pw1" class="label">Password</label>
<div id="pw_inst1"class="label_instruction"></div>
<input type="password" id="pw1" name="password" style="margin-bottom: 10px;" aria-describedby="pw_inst1">
<div class="login_buttons">
<input type="submit" value="Go" class="btn_go input-submit">
<input type="reset" class="btn_reset input-reset" value="Reset">
<br/>
</div>
</form>
<form id='user2' name='user2' method="post" role="form">
<input type="hidden" name="subsystem" value="resident"/>
<div class="usr-login label">Resident Login</div>
<label for="un2" class="label">Username</label>
<div id="un_inst2"class="label_instruction"></div>
<input autocapitalize="off" autocorrect="off" type="text" id="un2" name="username" value="" style="margin-bottom: 10px" aria-describedby="un_inst2">
<label for="pw2" class="label">Password</label>
<div id="pw_inst2"class="label_instruction"></div>
<input type="password" id="pw2" name="password" style="margin-bottom: 10px;" aria-describedby="pw_inst2">
<div class="login_buttons">
<input type="submit" value="Go" class="btn_go input-submit">
<input type="reset" class="btn_reset input-reset" value="Reset">
<br/>
</div>
</form>
在我的 featurecontext 文件中,我有这些函数:
public function iSubmitIncorrectCredentials($interface)
{
$button ='Go';
return $this->login("tester" . time(), "bar", $button);
}
private function login($username, $password, $btn)
{
$this->fillField('username', $username);
$this->fillField('password', $password);
$this->pressButton($btn);
}
其中 $interface 用于 user1 或 user2。我遇到的问题是 user1 的测试通过了,但是当我进行 user2 测试时,我得到这个错误:
{"errorMessage":"Element is not currently interactable and may not be manipulated","request":{"headers":{"Accept":"application/json;charset=UTF-8","Content-Length":"36","Content-Type":"application/json;charset=UTF-8","Host":"127.0.0.1:8643"},"httpVersion":"1.1","method":"POST","post":"{\"value\":[\"tester1479232631\ue004\"]}","url":"/value","urlParsed":{"anchor":"","query":"","file":"value","directory":"/","path":"/value","relative":"/value","port":"","host":"","password":"","user":"","userInfo":"","authority":"","protocol":"","source":"/value","queryKey":{},"chunks":["value"]},"urlOriginal":"/session/ea0f7000-ab5c-11e6-acb9-5946ec8fdb06/element/:wdc:1479232631203/value"}} (WebDriver\Exception\InvalidElementState)
我认为正在发生的事情是 fillField() 试图找到用户名字段,但有两个,所以对于 user1,测试有效,但对于 user2,我得到错误。除了更改 un/pw 字段的名称外,我还想获得有关如何处理此问题的一些建议。 谢谢
您需要为每个表单设置不同的选择器。您可以通过几种方式做到这一点:
对于前两种方法,您需要使用另一种方法来填充元素并单击字段,因为您将使用 css 选择器。
例如:找到元素-> click() 找到元素-> setValue()
1) 使用不同的选择器为每种类型创建一个方法
loginWithUser1($username, $password){...}
loginWithUser2($username, $password){...}
loginWithUser3($username, $password){...}
您将需要对以下元素使用 css 选择器:
#user1 input[name=username]
#user1 input[name=password]
2) 使用相同的方法和 build/read 基于参数
的数组选择器 login($username, $password, $role)
{
}
3) 使用页面对象功能
此选项将使用与第二个选项相同的方法,但不是从数组中读取选择器,而是使用 getElement() 方法并在该对象上使用您需要的方法。请在此处查看示例 working with elements
我建议尝试最后一个选项,如果您不能尝试第二个选项。
Tip: Avoid passing parameters in the method that you don't need like $btn from your login method.The method should know about the button element, you need to pass data only.