Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,17 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how

:microscope: - experimental

## [2.5.0]
Breaking change:
- :rocket: added step `I will wait for alert/dialog`

```gherkin
Scenario: accept alert
Given I will wait for dialog
Copy link
Contributor

@ALegchilov ALegchilov Feb 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be honest it is not obvious what this step is for, future tesnse confuses a bit.
Lets consider 2 other solutions:

  1. Rename the step to Given I set alert listener
    or more elegant solution
  2. Using BeforeAll hook check if some of pickles include 'alert' keyword and then set the listener.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For me listener is more programming specific. I want to use this I will wait for other types of event emitters available in playwright

Copy link
Contributor

@ALegchilov ALegchilov Feb 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given I expect alert will appear in this scenario

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expect already has meaning of assertion

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be honest I don't really like to make use of steps that dos not represent a business logic.
I know, this is not a silver bullet last option is adding a listener using a tag expression.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, but making it implicit will add more constraints and increase support cost

When I click 'Alert Button'
And I accept dialog
```

## [2.4.0]
- :rocket: added selector logging
- :rocket: added source maps
Expand Down
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ require('./lib/mock.js');
require('./lib/poDefine.js');
require('./lib/mouseActions.js');
require('./lib/keyboardActions.js');
require('./lib/dialog.js');
13 changes: 7 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@qavajs/steps-playwright",
"version": "2.4.0",
"version": "2.5.0",
"description": "steps to interact with playwright",
"main": "./index.js",
"scripts": {
Expand Down Expand Up @@ -28,7 +28,7 @@
"devDependencies": {
"@cucumber/cucumber": "^11.2.0",
"@qavajs/core": "^2.3.0",
"@qavajs/console-formatter": "^0.8.0",
"@qavajs/console-formatter": "^1.0.0",
"@qavajs/html-formatter": "^0.18.1",
"@qavajs/memory": "^1.10.2",
"@qavajs/webstorm-adapter": "^8.0.0",
Expand Down
35 changes: 0 additions & 35 deletions src/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,41 +294,6 @@ When('I upload {value} file by clicking {playwrightLocator}', async function (fi
await fileChooser.setFiles(await filePath.value());
});

/**
* Accept alert
* @example I accept alert
*/
When('I accept alert', async function () {
await new Promise<void>((resolve) => this.playwright.page.once('dialog', async (dialog: Dialog) => {
await dialog.accept();
resolve();
}));
});

/**
* Dismiss alert
* Playwright automatically dismisses all dialogs. This step is just to make it implicitly.
* @example I dismiss alert
*/
When('I dismiss alert', async function () {
await new Promise<void>((resolve) => this.playwright.page.once('dialog', async (dialog: Dialog) => {
await dialog.dismiss();
resolve();
}));
});

/**
* I type {string} to alert
* @example I type 'coffee' to alert
*/
When('I type {value} to alert', async function (value: MemoryValue) {
const typeValue = await value.value();
await new Promise<void>((resolve) => this.playwright.page.once('dialog', async (dialog: Dialog) => {
await dialog.accept(typeValue);
resolve();
}))
});

/**
* Drag&Drop one element to another
* @param {string} elementAlias - element to drag
Expand Down
75 changes: 75 additions & 0 deletions src/dialog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { When, Then } from '@cucumber/cucumber';
import { Dialog } from '@playwright/test';
import type {IQavajsWorld, MemoryValue, Validation} from '@qavajs/core';
import {IQavajsPlaywrightConfig} from "./IQavajsPlaywrightConfig";

class DialogHolder {
currentDialog!: Promise<Dialog>;
isListening: boolean = false;
}

const dialogHolder = new DialogHolder();

function checkIfListening(isListening: boolean) {
if (!isListening) {
throw new Error(`Step 'I will wait for alert/dialog' must be called before`);
}
}

/**
* Start listen for alert
* @example I will wait for dialog
*/
When('I will wait for alert/dialog', async function () {
dialogHolder.isListening = true;
dialogHolder.currentDialog = new Promise(resolve => this.playwright.page.once('dialog', resolve));
});

/**
* Accept alert
* @example I accept alert
*/
When('I accept alert/dialog', async function () {
checkIfListening(dialogHolder.isListening);
const dialog = await dialogHolder.currentDialog;
await dialog.accept();
});

/**
* Dismiss alert
* Playwright automatically dismisses all dialogs. This step is just to make it implicitly.
* @example I dismiss alert
*/
When('I dismiss alert/dialog', async function () {
checkIfListening(dialogHolder.isListening);
const dialog = await dialogHolder.currentDialog;
await dialog.dismiss();
});

/**
* I type {string} to alert
* @example I type 'coffee' to alert
*/
When('I type {value} to alert/dialog', async function (value: MemoryValue) {
checkIfListening(dialogHolder.isListening);
const typeValue = await value.value();
const dialog = await dialogHolder.currentDialog;
await dialog.accept(typeValue);
});

/**
* Verify that text of an alert meets expectation
* @param {string} validationType - validation
* @param {string} value - expected text value
* @example I expect text of alert does not contain 'coffee'
*/
Then(
'I expect text of alert/dialog {validation} {value}',
async function (validation: Validation, expected: MemoryValue) {
checkIfListening(dialogHolder.isListening);
const dialog = await dialogHolder.currentDialog;
const message = dialog.message();
const expectedValue = await expected.value();
validation(message, expectedValue);
}
);
17 changes: 0 additions & 17 deletions src/validations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,20 +279,3 @@ Then(
}
}
);

/**
* Verify that text of an alert meets expectation
* @param {string} validationType - validation
* @param {string} value - expected text value
* @example I expect text of alert does not contain 'coffee'
*/
Then(
'I expect text of alert {validation} {value}',
async function (validation: Validation, expected: MemoryValue) {
const alertText = await new Promise<string>(resolve => this.playwright.page.once('dialog', async (dialog: Dialog) => {
resolve(dialog.message());
}));
const expectedValue = await expected.value();
validation(alertText, expectedValue);
}
);
20 changes: 0 additions & 20 deletions test-e2e/features/actions.feature
Original file line number Diff line number Diff line change
Expand Up @@ -126,33 +126,13 @@ Feature: actions
When I upload '$uploadFile' file by clicking 'File Input'
Then I expect text of 'Action' to be equal 'file:C:\fakepath\actions.html'

Scenario: accept alert
When I click "Alert Button"
And I accept alert
Then I expect text of 'Action' to be equal 'true'

Scenario: dismiss alert
When I click "Alert Button"
And I dismiss alert
Then I expect text of 'Action' to be equal 'false'

Scenario: type text to alert
When I expect text of 'Action' to be equal 'Nothing'
And I click "Prompt Button"
And I type 'I am not a robot' to alert
Then I expect text of 'Action' to be equal 'I am not a robot'

Scenario: close current browser tab
When I expect current url to contain 'actions.html'
And I open new tab
And I switch to 2 window
And I close current tab
Then I expect current url to contain 'actions.html'

Scenario: expect text of alert
When I click "Prompt Button"
Then I expect text of alert to be equal 'Are you robot?'

Scenario: open new tab
When I open new tab
And I switch to 2 window
Expand Down
26 changes: 26 additions & 0 deletions test-e2e/features/dialog.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@debug
Feature: dialog

Background:
When I open '$actionsPage' url
And I will wait for dialog

Scenario: accept alert
When I click 'Alert Button'
And I accept dialog
Then I expect text of 'Action' to be equal 'true'

Scenario: dismiss alert
When I click 'Alert Button'
And I dismiss alert
Then I expect text of 'Action' to be equal 'false'

Scenario: type text to alert
When I expect text of 'Action' to be equal 'Nothing'
And I click 'Prompt Button'
And I type 'I am not a robot' to alert
Then I expect text of 'Action' to be equal 'I am not a robot'

Scenario: expect text of alert
When I click 'Alert Button'
Then I expect text of alert to be equal 'Are you robot?'
2 changes: 1 addition & 1 deletion test-e2e/features/validations.feature
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,6 @@ Feature: validations
Examples:
| collection | condition |
| Present Collection | to be present |
@debug

Scenario: collection css property
Then I expect 'background-color' css property of every element in 'Simple Text List Items' collection to be equal 'rgba(0, 0, 0, 0)'
2 changes: 1 addition & 1 deletion test-e2e/webui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const common = {
format: [
'@qavajs/console-formatter',
'junit:test-e2e/report.xml',
'@qavajs/html-formatter:test-e2e/report.html'
['@qavajs/html-formatter', 'test-e2e/report.html']
],
formatOptions: {
console: {
Expand Down