Skip to main content
Version: 2x

What's new in v2

  • new page object approach

page object now is built-in to corresponding UI library and exports single named export locator from /po sub-path.

playwright example:

import { locator } from '@qavajs/steps-playwright/po';

class App {
Button = locator('#button'); //simple locator
Row = locator.template(line => `.row:has-text("${line}")`); //template locator
Toast = locator.native(({ page }) => page.locator('.toast')); //native locator
Modal = locator('#modal').as(Modal); // component
}

class Modal {
Save = locator('#save');
}

wdio example:

import { locator } from '@qavajs/steps-wdio/po';

class App {
Button = locator('#button'); //simple locator
Row = locator.template(line => `.row:has-text("${line}")`); //template locator
Toast = locator.native(({ browser }) => browser.$('.toast')); //native locator
Modal = locator('#modal').as(Modal); // component
}

class Modal {
Save = locator('#save');
}
Scenario: new page object features
When I click 'Button'
Then I expect 'Row (Kyiv)' to be present # word in parenthesis become argument of template function
When I click 'Modal > Save'
And I expect 'Toast' to be visible
  • introduced playwrightLocator parameter type to transform page object alias to locator
When('I click {playwrightLocator}', async function (locator: Locator) {
await locator.click()
});
Scenario: new page object features
When I click 'Button'
  • introduced wdioLocator parameter type to transform page object alias to accessor function
When('I click {wdioLocator}', async function (locator: Locator) {
await locator().click()
});

When('I click first element in collection {wdioLocator}', async function (locator: Locator) {
await locator.collection()[0].click()
});
  • @qavajs/cli become @qavajs/core and provides shared types MemoryValue - memory data accessor (all qavajs steps works this accessor)
import { type MemoryValue } from '@qavajs/core';

When('I write {string} to {value}', function (data: string, memoryValue: MemoryValue) {
memoryValue.set(data);
});

When('I read {value} from memory', function (memoryValue: MemoryValue) {
console.log(memoryValue.value());
});
Scenario: new MemoryValue type
When I write '42' to 'theAnswer' # value with be saved to $theAnswer key
And I read '$theAnswer' from memory

Validation - resolver for validation logic

import { type Validation } from '@qavajs/core';

Then('I expect {string} {validation} {string}', function (actual: string, expect: Validation, expected: string) {
expect(actual, expected);
});

Then('I wait until {string} {validation} {string}', async function (actual: string, expect: Validation, expected: string) {
await expect.poll(actual, expected);
});
Scenario: new Validation type
Then I expect '41' not to equal '42'
But I expect '41' equal '41'
And I wait until '42' to be greater that '41'
  • exposed new getValue and setValue properties to qavajs world to access memory
When('I write {string} to memory', function (data: string) {
this.setValue('yourKey', data);
});

When('I read from memory', function (key: string) {
console.log(this.getValue('$yourKey'));
});
  • exposed new validation property to get expect function
When('I write {string} to memory', function (data: string) {
this.setValue('yourKey', data);
});

When('I read from memory', function (key: string) {
console.log(this.getValue('$yourKey'));
});
  • removed I wait until... steps from wdio and playwright plugins in favor of I expect... that support polling
  • removed Response... steps from api plugin in favor of I expect and property accessor
  • removed globals in favor using world properties this.browser for wdio and this.playwright for playwright
  • removed I switch to frame in playwright plugin in favor using frame locators

Migration guide

v1v2
I wait until... stepsI expect... steps
Element = $('selector')Element = locator('selector')
Collection = $$('selector')Collection = locator('selector')
Component = $(new Component('selector'))Component = locator('selector').as(Component)
class CustomComponent extends Component {}class CustomComponent {}
Element = $(Selector(text => `//*[@text="${text}"]`))Element => locator.template(text => `//*[@text="${text}"]`)
Element = $(NativeSelector(page => page.locator('selector'))Element = locator.native(page => page.locator('selector'))
getElement('Button')this.element() or use {wdioLocator}/{playwrightLocator} parameter type
getCollection('Button')this.element().collection() or use {wdioLocator}/{playwrightLocator} parameter type
memory.getValue('$key')this.getValue('$key') or use {value} parameter type
memory.setValue('key', 42)this.setValue('key', 42) or use {value} parameter type
getValidatiion('to equal')this.validation('to equal') or use {validation} parameter type
global.configthis.config
global.browser (wdio)this.wdio.browser
global.driver (wdio)this.wdio.driver
global.browser (playwright)this.playwright.browser
global.context (playwright)this.playwright.context
global.page (playwright)this.playwright.page