如何在量角器中为元素是否存在创建条件
How to create a condition in protractor for when an element exists or not
我正在使用 Protractor JS。网站是用 Angular JS 编写的。
所以我有一个拨动开关。我注意到切换开关中的值从 true 变为 false 并且
关闭或打开时从 false 变为 true。
我正在尝试创建一个条件,当 Protractor 访问我的页面时,当它看到切换开关 'off' 时,它将转动它 'on'。如果拨动开关已经是 'on',它会先将它转动 'off' 然后再转动它 'on'。
我想出了这段代码,但由于某种原因它不起作用:
if( expect(element(By.id('toggle-switch')).element(By.css('[value="false"]')).isDisplayed()) ) {
element(By.id('toggle-switch')).click();
console.log('in the if')
}
else{
element(By.id('toggle-switch')).click();
browser.sleep(3000);
element(By.id('toggle-switch')).click();
console.log('in the else')
}
此代码似乎仅适用于 if 语句。由于某种原因,它永远不会去其他地方。这是我收到的错误:
NoSuchElementError: 使用定位器找不到元素: By.cssSelector("[value=\"false\"]")
然后我试了
.isPresent()
而不是 .isDisplayed()
我不再收到上述错误,但由于某种原因,在使用 .isPresent() 时,它总是转到 if 语句并且只运行它,而从不运行 else 语句。没有显示错误。
如果有更好的方法请告诉我。这似乎非常有限,无法在此框架中创造适当的条件。
记住isDisplayed()
returns一个承诺,你可以试试:
element(anyFinder).isDisplayed().then(function(result) {
if ( result ) {
//Whatever if it is true (displayed)
} else {
//Whatever if it is false (not displayed)
}
});
isDisplayed()
对我不起作用。 API 可能已更改。 isPresent()
是我的解决方案:
var logoutButton = element(by.css('[ng-click="log_out()"]'));
logoutButton.isPresent().then(function(result) {
if ( result ) {
logoutButton.click();
} else {
//do nothing
}
});
或者尝试从我的脑海中实现这个解决方案,安排一个命令来测试页面上是否存在元素。如果在评估等待时发生任何错误,它们将被允许传播。
function alwaysSwitchOn(element) {
browser.driver.isElementPresent(element).then(function(isPresent) {
if (isPresent) {
isPresent = true;
}
else {
browser.driver.wait(function () {
return browser.driver.isElementPresent(element);
}, 5000);
}
// to fail the test, then uncomment this line
//expect(isPresent).toBeTruthy();
}).then(function () {
if (element.getAttribute('value') === 'OFF') {
element.click();
}
else {
// turn it OFF
element.click();
// turn it back ON
element.click();
}
});
}
fn的用法是反复尝试5秒,直到true
。如果在 5 sec
中找不到该元素,则会产生错误代码;没有这样的元素是found.Note,如果在等待(5s
)之前条件满足,它会迅速移动到then(...)
。
问题是 isDisplayed()
, as a lot of methods in WebDriverJS/Protractor, returns a promise 根据定义是 "truthy" 这使得调试此类问题变得困难。
让我们通过一个例子来加深理解。
想象一下,您有以下代码,乍一看可能没问题:
var elm = $("#myid");
if (elm.isDisplayed()) {
// do smth
} else {
// do smth else
}
现在,它有一个严重的问题。 do smth else
部分将永远不会达到 ,因为 elm.isDisplayed()
不是布尔值 - 它是一个承诺。即使不显示该元素,您仍然会执行 // do smth
部分。
相反,如果您需要检查 isDisplayed()
的值以在条件表达式中使用,则必须 显式 then()
解决承诺 :
var elm = $("#myid");
elm.isDisplayed().then(function (isDisplayed) {
if (isDisplayed) {
// do smth
} else {
// do smth else
}
});
还有一种方法可以在没有 运行 代码的情况下捕获此类错误 - 静态地使用 ESLint
and eslint-plugin-protractor
plugin. There is a relevant rule 监视是否在 if
条件中直接使用了某些 Protractor 方法。
以上代码的输出结果如下:
$ eslint test.js
test.js
2:1 warning Unexpected "isDisplayed()" inside if condition protractor/no-promise-in-if
如果您在 2021 年或之后的年份
忘记 .then()
。改为这样做:
it('test case', async () => {
if (await element(anyFinder).isDisplayed()) {
// Whatever if it is true (displayed)
} else {
// Whatever if it is false (not displayed)
}
});
我正在使用 Protractor JS。网站是用 Angular JS 编写的。
所以我有一个拨动开关。我注意到切换开关中的值从 true 变为 false 并且 关闭或打开时从 false 变为 true。
我正在尝试创建一个条件,当 Protractor 访问我的页面时,当它看到切换开关 'off' 时,它将转动它 'on'。如果拨动开关已经是 'on',它会先将它转动 'off' 然后再转动它 'on'。
我想出了这段代码,但由于某种原因它不起作用:
if( expect(element(By.id('toggle-switch')).element(By.css('[value="false"]')).isDisplayed()) ) {
element(By.id('toggle-switch')).click();
console.log('in the if')
}
else{
element(By.id('toggle-switch')).click();
browser.sleep(3000);
element(By.id('toggle-switch')).click();
console.log('in the else')
}
此代码似乎仅适用于 if 语句。由于某种原因,它永远不会去其他地方。这是我收到的错误:
NoSuchElementError: 使用定位器找不到元素: By.cssSelector("[value=\"false\"]")
然后我试了
.isPresent()
而不是 .isDisplayed()
我不再收到上述错误,但由于某种原因,在使用 .isPresent() 时,它总是转到 if 语句并且只运行它,而从不运行 else 语句。没有显示错误。
如果有更好的方法请告诉我。这似乎非常有限,无法在此框架中创造适当的条件。
记住isDisplayed()
returns一个承诺,你可以试试:
element(anyFinder).isDisplayed().then(function(result) {
if ( result ) {
//Whatever if it is true (displayed)
} else {
//Whatever if it is false (not displayed)
}
});
isDisplayed()
对我不起作用。 API 可能已更改。 isPresent()
是我的解决方案:
var logoutButton = element(by.css('[ng-click="log_out()"]'));
logoutButton.isPresent().then(function(result) {
if ( result ) {
logoutButton.click();
} else {
//do nothing
}
});
或者尝试从我的脑海中实现这个解决方案,安排一个命令来测试页面上是否存在元素。如果在评估等待时发生任何错误,它们将被允许传播。
function alwaysSwitchOn(element) {
browser.driver.isElementPresent(element).then(function(isPresent) {
if (isPresent) {
isPresent = true;
}
else {
browser.driver.wait(function () {
return browser.driver.isElementPresent(element);
}, 5000);
}
// to fail the test, then uncomment this line
//expect(isPresent).toBeTruthy();
}).then(function () {
if (element.getAttribute('value') === 'OFF') {
element.click();
}
else {
// turn it OFF
element.click();
// turn it back ON
element.click();
}
});
}
fn的用法是反复尝试5秒,直到true
。如果在 5 sec
中找不到该元素,则会产生错误代码;没有这样的元素是found.Note,如果在等待(5s
)之前条件满足,它会迅速移动到then(...)
。
问题是 isDisplayed()
, as a lot of methods in WebDriverJS/Protractor, returns a promise 根据定义是 "truthy" 这使得调试此类问题变得困难。
让我们通过一个例子来加深理解。
想象一下,您有以下代码,乍一看可能没问题:
var elm = $("#myid");
if (elm.isDisplayed()) {
// do smth
} else {
// do smth else
}
现在,它有一个严重的问题。 do smth else
部分将永远不会达到 ,因为 elm.isDisplayed()
不是布尔值 - 它是一个承诺。即使不显示该元素,您仍然会执行 // do smth
部分。
相反,如果您需要检查 isDisplayed()
的值以在条件表达式中使用,则必须 显式 then()
解决承诺 :
var elm = $("#myid");
elm.isDisplayed().then(function (isDisplayed) {
if (isDisplayed) {
// do smth
} else {
// do smth else
}
});
还有一种方法可以在没有 运行 代码的情况下捕获此类错误 - 静态地使用 ESLint
and eslint-plugin-protractor
plugin. There is a relevant rule 监视是否在 if
条件中直接使用了某些 Protractor 方法。
以上代码的输出结果如下:
$ eslint test.js
test.js
2:1 warning Unexpected "isDisplayed()" inside if condition protractor/no-promise-in-if
如果您在 2021 年或之后的年份
忘记 .then()
。改为这样做:
it('test case', async () => {
if (await element(anyFinder).isDisplayed()) {
// Whatever if it is true (displayed)
} else {
// Whatever if it is false (not displayed)
}
});