我如何为一个异步的变量赋值

时间:2018-02-22 11:23:49

标签: typescript appium

我有一个基于打字稿的Appium自动化框架。这里元素定位器策略本质上是异步的,因为我使用的插件本质上是异步的。(需要使用await)。在下面的代码中,我想在方法中使用settings _button值。但是因为我收到了错误

,所以我不能

弃用未处理的承诺拒绝。将来,未处理的承诺拒绝将使用非零退出代码终止Node.js进程。

findElementByText应该返回一个promise。这是Visual代码所说的,(方法)AppiumDriver.findElementByText(text:string,match?:SearchOptions,waitForElement?:number):Promise

export class HomeScreen extends BasePage {

settings_button = this._driver.findElementByText('Settings',10);

async isDisplayedSettings(){
    await (await this.settings_button).isDisplayed();
}

async openSettings(){
    await (await this.settings_button).click();

}

}

这在mocha测试框架中使用,就像这样。

describe("Firmware Update", () => {

let scanDevices: ScanDevices, genFunc: GenericFunctions, settings: SettingsScreen, homeScreen: HomeScreen;

const defaultWaitTime = 5000;
let driver: AppiumDriver;

before(async () => {
    driver = await createDriver();
    scanDevices = new ScanDevices(driver);
    homeScreen = new HomeScreen(driver);
    settings = new SettingsScreen(driver);
    genFunc = new GenericFunctions();
    await genFunc.timeDelay(10000); //Delay for the headset scan
    await scanDevices.clickHeadset();
});

after(async () => {
    await driver.quit();
    console.log("Quit driver!");
});


afterEach(async function () {
    if (this.currentTest.state === "failed") {
        await driver.logScreenshot(this.currentTest.title);
    }
});

it("should display settings option", async () => {
    assert.isTrue(await homeScreen.isDisplayedSettings(),"Option should be displayed");

});

it("should tap settings option", async () => {
    await homeScreen.openSettings();
    assert.isTrue(await settings.isDisplayeUpdatebutton(),"Expecting Settings screen to open");    

});

1 个答案:

答案 0 :(得分:0)

根据您的评论,显示警告的保证是存储在settings_button变量中的保证。

问题是如果某人创建了一个HomeScreen实例,但根本没有在该实例上调用任何方法, settings_button中的错误永远不会消耗,这被nodejs团队判定为致命错误。有 在构造函数中没有办法确保将来会调用其中一个方法。

在您的情况下,settings_button承诺始终在调用isDisplayedSettings之前解析,因为。{ 延迟before阻止。

您必须重新构建代码。有两种方法可以解决这个问题:

  • 等待初始化方法中的元素查询。没有异步counstructors所以你需要一个异步 工厂为此而来。我个人更喜欢这个解决方案。
  • 将元素查询推迟到第一次使用。这在语义上与您当前的代码相同,但在没有调用方法时可以防止未处理的错误问题。

使用伪代码:

解决方案1:

export class HomeScreen extends BasePage {
    settings_button : UIElement? = null;
    async init() {
        settings_button = await this._driver.findElementByText('Settings', 10);
    }
    static async create(driver) {
        const result = new HomeScreen(driver);
        await result.init();
        return result;
    }

    // ...
}

// ...

before(async() => {
    // ...
    homeScreen = await HomeScreen.create(driver);
    // ...
});

解决方案2:

export class HomeScreen extends BasePage {
    _settingsButtonPromise : Promise<UIElement>? = null;
    async getSettingsButton() {
        if (!this._settingsButtonPromise) {
            this._settingsButtonPromise = this._driver.findElementByText('Settings', 10);
        }
        return await this._settingsButtonPromise;
    }

    async isDisplayedSettings(){
        return await (await this.getSettingsButton()).isDisplayed();
    }

    // ...
}