0

tl;dr: When I run my test case, steps executed seem to work, but the test bails out early on a failure to find an element that hasn't even loaded yet. It seems like the waits I have around locating certain elements are loaded/launched as soon as the test is launched, not when the lines should actually be executed in the test case. I think this is happening because the page is barely (correctly) loaded before the "search" for the element to verify the page has loaded bails out. How do I wrangle the event loop?

This is probably a promise question, which is fine, but I don't understand what's going on. How do I implement my below code to work as expected? I'm working on creating automated E2E test cases using Jasmine2 and Protractor 5.3.0 in an Angular2 web app.

describe('hardware sets', () => {
    it('TC3780:My_Test', async function() {
      const testLogger = new CustomLogger('TC3780');
      const PROJECT_ID = '65';

      // Test Setup
      browser.waitForAngularEnabled(false); // due to nature of angular project, the app never leaves zones, leaving a macrotask constantly running, thus protractor's niceness with angular is not working on our web app
      // Navigate via URL to planviewer page for PROJECT_ID
      await planListingPage.navigateTo(PROJECT_ID);  // go to listing page for particular project
      await planListingPage.clickIntoFirstRowPlans(); // go to first plan on listing page
      await planViewerPage.clickOnSetItem('100'); // click on item id 100 in the plan
    });
  });

planViewerPage.po.ts function:

  clickOnSetItem(id: string) {
    element(by.id(id)).click();
    browser.wait(until.visibilityOf(element(by.css('app-side-bar .card .info-content'))), 30000); // verify element I want to verify is present and visible
    return expect(element(by.css('app-side-bar .card .info-content')).getText).toEqual(id);  //Verify values match, This line specifically is failing. 
  }

This is the test case so far. I need more verification, but it is mostly done. I switched to using async function and awaits instead of the typical (done) and '.then(()=>{' statement chaining because I prefer not having to do a bunch of nesting to get things to execute in the right order. I come from a java background, so this insanity of having to force things to run in the order you write them is a bit much for me sometimes. I've been pointed to information like Mozilla's on event loop, but this line just confuses me more:

whenever a function runs, it cannot be pre-empted and will run entirely before any other code runs (and can modify data the function manipulates).

Thus, why does it seem like test case is pre-evaluated and the timer's set off before any of the pages have been clicked on/loaded? I've implemented the solution here: tell Protractor to wait for the page before executing expect pretty much verbatim and it still doesn't wait.

Bonus question: Is there a way to output the event-loop's expected event execution and timestamps? Maybe then I could understand what it's doing.

The behavior

Community
  • 1
  • 1
S.Huston
  • 254
  • 6
  • 18

1 Answers1

0

The code in your function is running asynchronously

    clickOnSetItem(id: string) {
        element(by.id(id)).click().then(function(){
            return browser.wait(until.visibilityOf(element(by.css('app-side-bar .card .info-content'))), 30000); 
        }).then(function(){
           expect(element(by.css('app-side-bar .card .info-content')).getText).toEqual(id); 
         }).catch(function(err){
            console.log('Error: ' + err);
         })       
     }
Narm
  • 10,677
  • 5
  • 41
  • 54