在为登录流程运行UI测试时,用户可能已经登录。如果用户已登录,则需要首先执行注销。
在这种情况下,我必须等待登录或退出按钮出现,但我不知道会出现哪个。我想简单地等待一个或另一个出现,然后执行基于哪个操作首先返回。
我只是在尝试注销时添加了一个无声失败。如果操作超时,脚本将继续部分进入日志。
如果发生超时,则尝试注销并让它失败:
try {
const profileIconLocator = By.css('.frontpage-menu-item-icon-profile');
await browser.wait(Until.elementIsVisible(profileIconLocator));
const profileIcon = await browser.findElement(profileIconLocator);
assert.ok(await profileIcon.isDisplayed(), 'Ordbog profile icon button is visible');
await profileIcon.click();
const logOutLinkLocator = By.css('.frontpage-menu-dropdown-tools-item:nth-child(3)');
await browser.wait(Until.elementIsVisible(logOutLinkLocator));
const logOutLink = await browser.findElement(logOutLinkLocator);
assert.ok(await logOutLink.isDisplayed(), 'Log out link is visible');
await logOutLink.click();
} catch (error) {
console.log("LogOutStep: Failed to log out before logging in", error);
}
假设测试用户已注销,请尝试登录:
let signInButtonLocator = By.css('.frontpage-menu-item-icon-signin');
await browser.wait(Until.elementIsVisible(signInButtonLocator));
const signInButton = await browser.findElement(signInButtonLocator);
assert.ok(await signInButton.isDisplayed(), 'Sign in button is visible');
await signInButton.click();
我希望用户在登录之前始终会注销,但是对于每个测试用户而言,在第一次注销尝试中必须等待超时的UI测试并不理想。
理想的结果是我可以等待两个异步调用中的任何一个返回,在返回时取消另一个,然后执行如下函数:
// Wait for this to execute first(log out button)
const profileIconLocator = By.css('.frontpage-menu-item-icon-profile');
await browser.wait(Until.elementIsVisible(profileIconLocator));
// or this (sign in button)
let signInButtonLocator = By.css('.frontpage-menu-item-icon-signin');
await browser.wait(Until.elementIsVisible(signInButtonLocator));
// If sign in button shows first, run login
// If sign out button shows first, perform log out, then login again.
我可能试图过度简化问题,但我想你可以使用这样的模式,只有当另一个异步函数尚未解决时才有条件地对每个异步函数的结果起作用:
// Set flags
let firstPromiseResolved = false;
let secondPromiseResolved = false;
// Start asynchronous functions
firstPromise(resolve, reject).then(function(firstResult){
if(secondPromiseResolved === false){
// Maybe we want to use firstResult for some purpose here?
firstPromiseResolved = true; // Set flag so the other function won't log us out
login(); // Do the thing
}
}
secondPromise(resolve, reject).then(function(secondResult){
if(firstPromiseResolved === false){
// Maybe we want to use secondResult for some purpose here?
secondPromiseResolved = true; // Set flag so the other function won't log us in
logoutAndlogin(); // Do the other thing
}
}
我最后通过使用等待一个或另一个CSS类的第一个实例的多查询选择器来解决它。所以在这里我等待登录按钮或退出按钮首先出现,然后根据出现的元素的类进行操作:
const profileIconOrSignInButtonLocator = By.css('.frontpage-menu-item-icon-profile, .frontpage-menu-item-icon-signin');
await browser.wait(Until.elementIsVisible(profileIconOrSignInButtonLocator));
const loginOrLogoutButton = await browser.findElement(profileIconOrSignInButtonLocator);
var elementClass = await loginOrLogoutButton.getAttribute('class');
if (elementClass === 'frontpage-menu-item-icon frontpage-menu-item-icon-signin') {
console.log("Simply log in");
await loginFrontPage(browser);
} else { // If this happens we're already logged in, and need to log out first.
console.log("Log out and then log in");
await logoutFrontPage(browser);
await loginFrontPage(browser);
}