Testing Two Pages in an App Sequentially with Protractor and Angular

I want to execute Protractor tests on two distinct pages in my Angular app: /dashboard and /articles.

The challenge lies in the fact that I need to manually log into the application.

Currently, this is how it's set up:

var LoginPage = function() {
  ptor = protractor.getInstance();
  this.login = function(url) {
    ptor.get(url);
    ptor.findElement(protractor.By.model('email')).sendKeys(config.LOGIN_EMAIL);
    ptor.findElement(protractor.By.model('password')).sendKeys(config.LOGIN_PASS);
    ptor.findElement(protractor.By.tagName('button')).click();
  };
};

describe('The dashboard', function() {
  console.log('logging in');
  var loginPage = new LoginPage();
  loginPage.login(config.DASHBOARD_URL);
  console.log('logged in');
  it('has a heading', function() {
    console.log('testing dashboard 1');
    heading = ptor.findElement(protractor.By.tagName('h1'));
    expect(heading.getText()).toEqual(config.DASHBOARD_HEADING);
  });
});

describe('The article widget', function() {
  console.log('logging in');
  var loginPage = new LoginPage();
  loginPage.login(config.ARTICLE_URL);
  console.log('logged in');
  it('has a heading', function() {
    console.log('testing article 1');
    heading = ptor.findElement(protractor.By.tagName('h1'));
    expect(heading.getText()).toEqual(config.ARTICLES_HEADING);
  });
});

This results in the following output:

Selenium standalone server started at http://192.168.2.9:56791/wd/hub
logging in
LoginPage
logged in
logging in
LoginPage
logged in
testing dashboard 1
Ftesting article 1

It seems like both describe sections are running in parallel. How can I ensure the desired sequence of events while maintaining an organized code structure?

  1. Load the dashboard page
  2. Log in
  3. Execute dashboard tests
  4. Load the article page (assuming we are already logged in)
  5. Run article tests

Answer №1

To reorganize your code, consider moving the login functionality to a separate file.

Next, update your protractor configuration file as shown below:

exports.config = {
  specs: [
    'spec/login.js',
    'spec/dashboard_test.js',
    'spec/article_test.js'
  ],
  ...
};

This adjustment ensures that the login process occurs before running any other tests.

Answer №2

When it comes to 'my app', one must remember to first login and then navigate through the dashboard and explore the article widget.

Answer №3

The Protractor documentation suggests implementing your log-in code in an onPrepare function, which executes once before any test runs.

This can be done in the protractor.conf file as shown below:

onPrepare: function() {
    browser.driver.get('http://localhost/login.html');

    browser.driver.findElement(by.id('username')).sendKeys('Jane');
    browser.driver.findElement(by.id('password')).sendKeys('1234');
    browser.driver.findElement(by.id('clickme')).click();

    // Waiting for login to complete
    return browser.driver.wait(function() {
       return browser.driver.getCurrentUrl().then(function(url) {
          return /index/.test(url);
       });
    }, 10000);
}

Answer №4

I encountered a problem with my e2e protractor tests where describe blocks were running in parallel, leading to test failures.

Initially, my code looked like this:

describe('test1', function() {
  it('do foo1', function() {..});
  describe('do test1', function() {..});
});
describe('test2', function() {
  it('do foo2', function() {..});
  describe('do test2', function() {..});
});

Both describe blocks were executing simultaneously causing test failures. I resolved this issue by enclosing the it blocks within describe blocks.

Here is the updated code:

describe('test1', function() {
  describe('foo1', function() {
    it('do foo1', function() {..});  
  });
  describe('do test1', function() {..});
});
describe('test2', function() {
  describe('foo2', function() {
    it('do foo2', function() {..});  
  });
  describe('do test2', function() {..});
});

For a similar issue related to protractor on github, check out: https://github.com/angular/protractor/issues/592

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Chrome will automatically retry an AJAX POST request if it times out after 10 seconds

I am in the process of creating a React JavaScript application using a back end powered by Node.js and Express. The software versions being used are as follows: React: ^16.0.0 Node: v8.0.0 Express: ^4.14.0 Chrome: Version 63.0.3239.84 (Official Build) (64 ...

Leveraging the power of Google Charts along with MySQL or

I've been working on this task for several days now and I'm still struggling to achieve the desired outcome. My goal is to dynamically create a column/bar chart using Google Charts, populated with data from my database. Here's my query: SE ...

Issue with AngularJS dropdown visibility on Internet Explorer 9

After testing the code below in Chrome and confirming it works, I encountered issues when trying it in IE9. Despite upgrading my AngularJS version to v1.2.16 along with angular.min.js, the dropdown results still wouldn't show up. <div id="ng-app" ...

Empty Restangular POST Request Body

My goal is to send a request to /api/sessions using Restangular. Here's how I have set up my code: var data = { "email": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="dbaea8bea99bbeb6bab2b7f5b8b4b6">[email prote ...

Unable to retrieve input values from the text fields using JavaScript

In my project, I have created two PHP pages - "doc.php" and "chkval.php". The issue I am facing is that the textfield values are not being captured in the "chkval.php" page using $POST method. An error that I encountered is: Use of undefined constant re ...

Tips on emulating typing actions in an input field during a Jest test

I am working on a component that displays type-ahead suggestions as the user types in a text field. The suggestions are fetched from a server based on the input provided by the user. I want to test this functionality by simulating a scenario where the us ...

Restricting href Usage Based on Session

I find myself in a challenging situation without a clear solution at hand. Within this code, I am utilizing a link and a button for which I need to save the page in a database. Therefore, creating a server control is not an option as it will not be render ...

Issues arise with AJAX post

I have run into an issue with my jQuery and Codeigniter setup while trying to update the database via AJAX. Despite having the following code in place, nothing seems to be happening or getting sent to my controller when the button is clicked... Snippet of ...

Looking for a way to focus on an element similar to `event.target.focus()`

I am in the process of developing a dynamic list component that generates an empty text field every time an item is added to the list. The structure of the component is shown below: const DynamicInputList = ({ inputs, onChangeArray, label, name, errors }) ...

Maintain the structure of ajax POST requests and display a real-time feed of

I've been developing an openvz script to run virtual machines at home. I've been exploring JavaScript and AJAX functions to send post requests, which are then displayed in the innerHTML section of my webpage. However, I've encountered an iss ...

Conceal or reveal radio buttons according to information in a table

How can I dynamically add and remove values from a table based on radio button selections? My goal is to add the selected value to the table and hide it from the radio button list, and if the value is deleted from the table, I want to show it back in the r ...

There appears to be a issue with BINDING functionality within Angular

When using two select fields, selecting an item in the first should automatically fill the second with the corresponding subarray. While this functionality works, adding a new field results in all other selections changing as well. How can I prevent this f ...

What could be causing this code to malfunction when using D3.min version instead?

In this coding example, a scale and an axis object can be seen in the console: <!DOCTYPE html> <head> </head> <body> <script src="//d3js.org/d3.v5.js"></script> <script> console.log(d3.scale ...

Updating information with AJAX upon clicking a hyperlink

I am trying to implement AJAX for replacing the contents within a div. The setup of the application is quite complex, but I have simplified it to focus on getting the basic concept to work first. Currently, my goal is simply to replace a div based on the ...

Can a background image flow into another div?

My goal is to use this specific image as the background image for this particular page. I want the background image to begin within the navbar navbar-default class. However, I'm facing an issue. I need the image to extend into the next div, which is d ...

Refresh your AngularJS Bindonce directives with the power of the refreshOn attribute

After making some edits to my bindonce table, I am attempting to force refresh it. However, I am struggling to understand how to utilize the bindonce refreshOn attribute. Here is my HTML Code: <tbody bindonce="filteredItems" refresh-on="refreshTaskLis ...

What are some strategies for efficiently displaying a large amount of data on a screen using Javascript and HTML without sacrificing performance?

Imagine having a hefty 520 page book with over 6,200 lines of text ranging from 5 to 300 characters each. The challenge lies in efficiently displaying this content on the screen for users to read without causing lag or performance issues. Attempting to re ...

The functionality of Angular animate becomes compromised when there is a conflict between predefined CSS states and transition states

Explore this example CSS code: /* animations at the start */ .error-animation.ng-enter { -webkit-transition: 0.5s linear all; transition: 0.5s linear all; opacity: 0; } ...

Altering the background colour of dropdown fields when clicking on a checkbox

How can I make the colors of my dropdown fields match the colors of the text (non-dropdown) fields when they are disabled using a checkbox? This is how my code looks: <form v-on:submit.prevent :disabled="isDisabled(opti ...

creating a countdown timer for the carousel

While experimenting, I decided to create a basic carousel from scratch. Initially, I used onclick="function()" to cycle through the images. Later on, I attempted to replace it with onload="setInterval(function, 4000)", but it seems like something went wron ...