How to wait for the backend in Protractor?

别来无恙 提交于 2019-12-23 01:12:40

问题


I'm testing a web page where the user can send a message to another via a textinput. A POST request is then send on the server and the message is dumped on the disk in the var/mail/new folder.

After automatising the sending of the message in the page with Protractor I'm calling browser.waitForAngular() and browser.driver.sleep(4000) to leave time for the backend to write the mail on the disk.

After these calls the check of the email's presence fails. When looking in the Unix shell, I can confirm that the email was sent and also the next test marked with in Jasmine with it confirms the presence of the email.

Why is browser.driver.sleep(4000) not effective to wait for the backend to proceed? How can I correct the following code?

it("is possible to send a message", function() {
    shared.loginContributor();

    var mailsBeforeMessaging =
        fs.readdirSync(browser.params.mail.queue_path + "/new");
    console.log('mailsBeforeMessaging');
    console.log(mailsBeforeMessaging.length);
    console.log(fs.lstatSync(browser.params.mail.queue_path + "/new"));

    var usersListing = new UserPages.UsersListing().get();
    var annotatorPage = usersListing.getUserPage("annotator");

    annotatorPage.sendMessage("title5", "content64");

    exec("/tmp/check.sh");

    // we expect the message widget to disappear
    var button = element(by.css(".user-profile-info-button"));
    console.log('waiting');
    browser.wait(EC.elementToBeClickable(button), 5000);
    console.log('waiting is finished');
    expect(EC.elementToBeClickable(button)).toBeTruthy();

    // wait for mail to be dumped on the disk?
    browser.waitForAngular();
    browser.driver.sleep(4000);

    exec("/tmp/check.sh");

    var mailsAfterMessaging =
        fs.readdirSync(browser.params.mail.queue_path + "/new");
    console.log('mailsAfterMessaging');
    // ERROR: here the number of emails is NOT incremented
    console.log(mailsAfterMessaging.length);
    console.log(fs.lstatSync(browser.params.mail.queue_path + "/new"));
});

it("xyz", function() {

    console.log(fs.lstatSync(browser.params.mail.queue_path + "/new"));
    // here the number of emails is incremented
    var mailsAfterMessaging =
        fs.readdirSync(browser.params.mail.queue_path + "/new");
    console.log('mailsAfterMessaging');
    console.log(mailsAfterMessaging.length);
});

回答1:


Most of the Protractor functions do not do anything. They queue something up to be done later, and return promise to do it. After an it block schedules a bunch of things to do, they actually start happening (via the promises they registered in the ControlFlow).

Your checks, however, are all executing immediately. So, they are happening before any of the protractor calls accomplish anything.

Use then to make the waiting and dependencies explicit in your test. Like this:

annotatorPage.sendMessage("title5", "content64").then(function() {
    exec("/tmp/check.sh");
});

or:

browser.wait(EC.elementToBeClickable(button), 5000).then(function() {
   console.log('wait-for-clickable has completed'); // B
});
console.log('wait-for-clickable has been scheduled'); // A

See the Protractor Control Flow documentation and the Webdriver JS API doc.

Its not you. This is a crazy API to learn because it does not act at all like anyone familiar with normal synchronous programming would expect.



来源:https://stackoverflow.com/questions/28808137/how-to-wait-for-the-backend-in-protractor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!