Mastering the art of writing protractor scenarios

In a hypothetical scenario where an Angular app consists of two pages - one for contacts (featuring a table with contacts and an "add new contact" button) and another for adding a new contact, the following steps can be outlined:

  1. Click on the "add" button
  2. Verify that the "new contacts" page opens
  3. Enter the contact's details
  4. Press the "add" button
  5. Confirm that the new contact appears in the table

For these pages, there are predefined page objects with functions such as "clicking a button" or "entering data into a field", each of which returns promises.

When it comes to writing the test scenario, one approach could be chaining methods using JavaScript, like so:

contactPage.clickAddButton()
.then(function () {
    return newContactPage.checkUrl();
})
.then(function () {
    return newContactPage.inputData(data);
})
.then(function () {
    return newContactPage.clickAddButton();
})
.then(function () {
    return checkContact(data);
})
.then(function (success) {
}, function (error) {
    console.error(error);
});

Alternatively, the scenario can also be written without method chaining, simply executing each action sequentially:

contactPage.clickAddButton();
newContactPage.checkUrl();
newContactPage.inputData(data);
newContactPage.clickAddButton();
checkContact(data);

Furthermore, considering whether to split the scenario into multiple "it" functions is another aspect worth contemplating.

Answer №1

Protractor takes care of handling promises without the need for explicit resolution. It utilizes a Control Flow to manage the promise queue seamlessly. For this specific scenario, it is recommended to keep all the actions within a single it(), unless there is repetition involved:

homePage.clickLoginButton();
loginPage.enterCredentials(username, password);
loginPage.clickSubmitButton();
checkLoginStatus();

Answer №2

If you prefer to stick with the protractor method, follow the advice given by alecxe in this answer.

However, if you want to maintain a clear chain of promises (such as for consistency with app coding format), here is how you could rewrite it:

contactPage.clickAddButton()
  .then(newContactPage.checkUrl) // Data must be resolved for next function
  .then(newContactPage.inputData) 
  .then(newContactPage.clickAddButton) // Data must be resolved for next function
  .then(checkContact)
  .then(function (success) {
    // Test passes...
  }, function (error) {
    console.error(error);
  });

On the other hand, if you are using protractor, following alecxe's solution would be a cleaner approach.

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

How can I retrieve text that is enclosed within 2 specific tags and then format the output according to my preference?

Is it possible to extract text between specific tags and format the output as desired? Are there any tools or scripts available for this task? For instance: [b]1.[/b] [artist]Norman Bass[/artist] – How U Like Bass? (Warp Brothers Club Mix) [i](3:26 ...

Implementing a JavaScript confirmation based on an if-else statement

I need to display a confirmation dialog under certain conditions and then proceed based on the user's response of yes or no. I attempted the following approach. Here is the code in aspx: <script type="text/javascript> function ShowConfirmati ...

Issue with showing error messages in view when using ejs templates

I am a beginner with node.js and I'm struggling to show error messages in the view using ejs templates. I want to display This user already exists. Here is my code: node.js router.post('/signup', (req, res) => { var username = req. ...

Can we programmatically switch to a different mat-tab that is currently active?

Looking to programmatically change the selected mat-tab in a TypeScript file. I came across a solution for md-tab, but I need it for mat-tab. I attempted the suggested solution without success. Here's what I tried: HTML <button class="btn btn- ...

Having trouble getting Vuejs to work when appending an element to Fullcalender

Hi there, I am facing an issue where appending a custom button to a full calendar event is not working properly with Vue.js methods. It works fine with core JavaScript, but I really want it to work with Vue.js methods. Any ideas on how I can achieve this? ...

Find the item in the pop-up window

When removing a user from my list, a JavaScript popup pops up prompting to confirm the action with two buttons "OK" / "Annuler" : Is there a way to use Selenium to find and interact with these buttons? ...

Do we really need Renderer2 in Angular?

Angular utilizes the Renderer2 class to manipulate our view, acting as a protective shield between Angular and the DOM, making it possible for us to modify elements without directly interacting with the DOM ourselves. ElementRef provides another way to al ...

"Ionic with Angular is facing an issue where ion-radio element cannot be set as checked by default

Having trouble selecting a radio button in a radio list. Can anyone help? Any assistance would be greatly appreciated. This is how I've been attempting it: <div class="list"> <ion-radio ng-repeat="item in goalTypeList" ...

I am looking to transfer the value of one textbox to another textbox within a dynamic creation of textboxes using JavaScript

var room = 1; function add_fields() { room=$('#row_count').val()-1; room++; var objTo = document.getElementById('education_fields'); var divtest = document.createElement("div"); divtest.setAttribute("class", "form- ...

Locate the unique symbol within an array

I am facing a challenge with validating user input in an input box where alphanumeric values are allowed along with certain special characters. I need to display an error message if the user enters a special character that is not supported by my applicatio ...

Dynamic Rendering of Object Arrays in Table Columns using JavaScript

In the process of developing an appointment slot selection grid, I have successfully grouped all appointments by dates. However, I am facing challenges in displaying this array of Objects as a clickable grid with columns. The current output can be viewed h ...

Refuse to alter the status of the checkbox

Is there a way to prevent any checkbox state from being changed? window.blockCheckboxChange = function(event) { e = event || window.event; if (e) { e.stopPropagation(); e.preventDefault(); var t = $(e.target); t.prop({checked: typeof ...

Creating JavaScript objects through function calls

let getBoxWidth = function() { this.width=2; }; alert(getBoxWidth.width); Hello there! Can you explain why the output is undefined in this scenario? ...

The current date object in JavaScript will only display the year or a combination of the month and

$scope.articles = [ { link: "http://google.com", source: "Google", title: "hello", "date": new Date(2008, 4, 15) }, ]; <tbody> <tr ng-repeat = "article in articles | orderBy:sortType:sortReverse | filter:searchArticle ...

Running an Express middleware function

While watching a tutorial on the Express framework, I came across some interesting code used by the instructor for handling requests. Here is how the route is set up: router.route('/').post(authController.restrictTo('admin', 'l ...

When using Node Puppeteer, if the page.on( "request" ) event is triggered, it will throw an error message stating "Request is already being handled!"

I am currently utilizing puppeteer-extra in conjunction with node.js to navigate through multiple URLs. During each iteration, I am attempting to intercept certain types of resources to load and encountering the error below. PS C:\Users\someuser ...

Connect my Vue.js model data to the object that will be used for submission

I need help figuring out how to bind data from my input field into my Vue.js model. I've tried putting the UnitName inside the model but it's not working. Can someone provide some guidance on how to achieve this? new Vue({ el: "#app", da ...

Leveraging backstretch.js in combination with blur.js (or equivalent)

Query Update I provided a response to the query below, however, I am experiencing some lag and a noticeable stepped transition between images. Can anyone offer advice on how to optimize this issue? Perhaps it would be better to go back to using a static ...

Tips for saving an image link when displaying an image in VueJS using the 'require' method

I am currently working on a project that involves displaying Pizza items with their respective images. Each Pizza object is stored in the database along with an imgUrl field. Strangely, the images are not showing up on the page, although I can see the alt ...

Next.js optimizes the page loading process by preloading every function on the page as soon as it loads, rather than waiting for them to

My functions are all loading onload three times instead of when they should be called. The most frustrating issue is with an onClick event of a button, where it is supposed to open a new page but instead opens multiple new pages in a loop. This creates a c ...