根据第一个异步调用 returns 执行函数

Execute function depending on which async call returns first

虽然 运行 对登录流程进行 UI 测试,但用户可能已经登录。如果用户已登录,则需要先执行注销。

在这种情况下,我必须等待登录或退出按钮出现,但我不知道会出现哪个。我想简单地等待一个或另一个出现,然后根据第一个 returns 执行操作。

我只是在尝试注销时添加了静默失败。如果操作超时,脚本只是继续进入日志部分。

尝试注销并在发生超时时让它失败:


        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-test 在每个测试用户的第一次注销尝试中必须等待超时是不理想的。

理想的结果是我可以等待对 return 的两个异步调用中的任何一个,在 return 上取消另一个,然后执行这样的函数:

// 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 class 的第一个实例的多查询选择器。所以我在这里等待登录按钮或注销按钮先出现,然后根据出现的元素的 class 进行操作:

    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);
    }