Skip to content

Commit

Permalink
fix(catalog): migrate e2e tests to BDD tests
Browse files Browse the repository at this point in the history
ref: MANAGER-14240

Signed-off-by: Nicolas Pierre-charles <nicolas.pierre-charles.ext@corp.ovh.com>
  • Loading branch information
Nicolas Pierre-charles committed Apr 23, 2024
1 parent 7dc90ae commit fafdc89
Show file tree
Hide file tree
Showing 37 changed files with 1,108 additions and 457 deletions.
2 changes: 2 additions & 0 deletions packages/manager/apps/catalog/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
e2e/reports
e2e/coverage
19 changes: 19 additions & 0 deletions packages/manager/apps/catalog/cucumber.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const isCI = process.env.CI;

module.exports = {
default: {
paths: ['e2e/features/**/*.feature'],
require: [
'../../../../playwright-helpers/bdd-setup.ts',
'e2e/**/*.step.ts',
],
requireModule: ['ts-node/register'],
format: [
'summary',
isCI ? 'progress' : 'progress-bar',
!isCI && ['html', 'e2e/reports/cucumber-results-report.html'],
!isCI && ['usage-json', 'e2e/reports/cucumber-usage-report.json'],
].filter(Boolean),
formatOptions: { snippetInterface: 'async-await' },
},
};
32 changes: 0 additions & 32 deletions packages/manager/apps/catalog/e2e/Error.e2e.ts

This file was deleted.

147 changes: 0 additions & 147 deletions packages/manager/apps/catalog/e2e/FilterAndSearch.e2e.ts

This file was deleted.

12 changes: 12 additions & 0 deletions packages/manager/apps/catalog/e2e/features/error.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Feature: Error

Scenario Outline: Display an error if request fails
Given The service to fetch the catalog is <apiOk>
When User navigates to catalog
Then User "<sees>" the list of products
Then User sees <anyError> error

Examples:
| apiOk | sees | anyError |
| OK | sees | no |
| KO | doesn't see | an |
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Feature: Associate a vRack to a vRack Services

Scenario Outline: Filter results based on Universe
Given User wants to filter products by universes "<universes>"
When User selects the universes in the filters
And User apply the search
Then User sees <nbProducts> products corresponding to the universe

Examples:
| universes | nbProducts |
| Bare Metal Cloud | 5 |
| Bare Metal Cloud,Web PaaS | 0 |

Scenario: Clears all filters
Given User filtered the products with an universe
When User clicks on the Clear All button
Then User sees all the products of the catalog

Scenario: Clear filter when chip is removed
Given User filtered the products with an universe
When User click on the remove button of a filter
Then The corresponding chip is removed
Then User sees all the products of the catalog
60 changes: 60 additions & 0 deletions packages/manager/apps/catalog/e2e/step-definitions/error.step.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { Given, When, Then } from '@cucumber/cucumber';
import { expect } from '@playwright/test';
import { ICustomWorld, sleep } from '../../../../../../playwright-helpers';
import { ConfigParams, getUrl, setupNetwork } from '../utils';
import { title } from '../../src/public/translations/catalog/Messages_fr_FR.json';
import {
manager_error_page_title,
manager_error_page_action_home_label,
manager_error_page_action_reload_label,
} from '../../src/public/translations/catalog/error/Messages_fr_FR.json';

Given('The service to fetch the catalog is {word}', function(
this: ICustomWorld<ConfigParams>,
apiState: 'OK' | 'KO',
) {
this.handlersConfig.isKo = apiState === 'KO';
});

When('User navigates to catalog', async function(
this: ICustomWorld<ConfigParams>,
) {
await setupNetwork(this);
await this.page.goto(this.testContext.initialUrl || getUrl('root'), {
waitUntil: 'load',
});
});

Then('User {string} the list of products', async function(
this: ICustomWorld<ConfigParams>,
see: 'sees' | "doesn't see",
) {
if (see === 'sees') {
await sleep(1000);

const titleElement = await this.page.locator('osds-text', {
hasText: title,
});
await expect(titleElement).toBeVisible();

const products = await this.page.locator('osds-tile').all();
await expect(products).toHaveLength(40);
}
});

Then('User sees {word} error', async function(
this: ICustomWorld<ConfigParams>,
anyError: 'an' | 'no',
) {
if (anyError === 'an') {
await expect(this.page.getByText(manager_error_page_title)).toBeVisible();

await expect(
this.page.getByText(manager_error_page_action_home_label),
).toBeVisible();

await expect(
this.page.getByText(manager_error_page_action_reload_label),
).toBeVisible();
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { expect } from '@playwright/test';
import { Given, When, Then } from '@cucumber/cucumber';
import { ICustomWorld, sleep } from '../../../../../../playwright-helpers';
import { no_result } from '../../src/public/translations/catalog/Messages_fr_FR.json';
import {
manager_catalog_filters_button_apply,
manager_catalog_filters_reset,
} from '../../src/public/translations/catalog/filters/Messages_fr_FR.json';
import { manager_catalog_search_filter_button } from '../../src/public/translations/catalog/search/Messages_fr_FR.json';
import { ConfigParams, selectFilters, setupE2eCatalogApp } from '../utils';

Given('User wants to filter products by universes {string}', function(
this: ICustomWorld<ConfigParams>,
universes: string,
) {
this.testContext.data.filters = universes
.split(',')
.map((universe) => universe.replace(/\s/gm, '_'));
});

Given('User filtered the products with an universe', async function(
this: ICustomWorld<ConfigParams>,
) {
this.testContext.data.filters = ['Bare_Metal_Cloud'];

await setupE2eCatalogApp(this);
await selectFilters(this);
await this.page.getByText(manager_catalog_filters_button_apply).click();
});

When('User selects the universes in the filters', async function(
this: ICustomWorld<ConfigParams>,
) {
await setupE2eCatalogApp(this);
await selectFilters(this);
});

When('User apply the search', async function(this: ICustomWorld<ConfigParams>) {
await this.page.getByText(manager_catalog_filters_button_apply).click();
});

When('User clicks on the Clear All button', async function(
this: ICustomWorld<ConfigParams>,
) {
await this.page.getByText(manager_catalog_search_filter_button).click();
await this.page.getByText(manager_catalog_filters_reset).click();
});

When('User click on the remove button of a filter', async function(
this: ICustomWorld<ConfigParams>,
) {
await this.page.locator('osds-chip osds-icon').click();
});

Then('User sees {int} products corresponding to the universe', async function(
this: ICustomWorld<ConfigParams>,
nbProducts,
) {
const nb = await this.page.locator('osds-tile').count();
await expect(nb).toBe(nbProducts);

if (nb === 0) {
const noResultText = await this.page.getByText(no_result);
await expect(noResultText).toBeVisible();
}
});

Then('The corresponding chip is removed', async function(
this: ICustomWorld<ConfigParams>,
) {
const nbChips = await this.page.locator('osds-chip').count();
await expect(nbChips).toBe(0);
});

Then('User sees all the products of the catalog', async function(
this: ICustomWorld<ConfigParams>,
) {
const nb = await this.page.locator('osds-tile').count();
await expect(nb).toBe(40);
});
9 changes: 9 additions & 0 deletions packages/manager/apps/catalog/e2e/utils/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const appUrl = 'http://localhost:9001/app';

export const urls = {
root: '/',
};

export type AppRoute = keyof typeof urls;

export const getUrl = (route: AppRoute) => `${appUrl}${urls[route]}`;
Loading

0 comments on commit fafdc89

Please sign in to comment.