Skip to content

Commit a7d700e

Browse files
authored
refactor: Cypress tests to use cucumber MAASENG-5318 (#5894)
1 parent 7907241 commit a7d700e

File tree

9 files changed

+1654
-62
lines changed

9 files changed

+1654
-62
lines changed

cypress.config.ts

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import { addCucumberPreprocessorPlugin } from "@badeball/cypress-cucumber-preprocessor";
2+
import { createEsbuildPlugin } from "@badeball/cypress-cucumber-preprocessor/esbuild";
3+
import createBundler from "@bahmutov/cypress-esbuild-preprocessor";
14
import { defineConfig } from "cypress";
25

36
export default defineConfig({
@@ -9,25 +12,51 @@ export default defineConfig({
912
"www.google-analytics.com",
1013
"sentry.is.canonical.com",
1114
],
15+
1216
// We've imported your old cypress plugins here.
1317
// You may want to clean this up later by importing these.
14-
setupNodeEvents(on, config) {
18+
// Here we use any type as Cypress’s on function supports many different event types, but its TypeScript definitions
19+
// only fully cover "task", so strictly typing on causes errors for other events like "file:preprocessor"
20+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
21+
async setupNodeEvents(on: any, config) {
22+
await addCucumberPreprocessorPlugin(on, config);
1523
on("task", {
16-
log(args) {
24+
log(args: unknown) {
1725
console.log(args);
1826

1927
return null;
2028
},
21-
table(message) {
29+
table(message: unknown) {
2230
console.table(message);
2331

2432
return null;
2533
},
2634
});
35+
const jsBundler = createBundler({});
36+
37+
on("file:preprocessor", (file: Cypress.FileObject) => {
38+
if (file.filePath.endsWith(".feature")) {
39+
return createBundler({
40+
plugins: [createEsbuildPlugin(config)],
41+
})(file);
42+
}
43+
44+
if (
45+
file.filePath.match(/\.(js|ts|jsx|tsx)$/) &&
46+
!file.filePath.endsWith(".steps.ts")
47+
) {
48+
return jsBundler(file);
49+
}
50+
51+
return undefined;
52+
});
2753
return config;
2854
},
2955
baseUrl: "http://0.0.0.0:8400",
30-
specPattern: "cypress/e2e/**/*.{js,jsx,ts,tsx}",
56+
specPattern: [
57+
"cypress/e2e/**/*.{js,jsx,ts,tsx}",
58+
"cypress/e2e/**/*.feature",
59+
],
3160
viewportHeight: 1300,
3261
viewportWidth: 1440,
3362
},
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Feature: Footer
2+
3+
Background:
4+
Given the user is logged in
5+
And the user is on the home page
6+
7+
Scenario: Navigating to the local documentation
8+
When the user looks for the "local documentation" link
9+
Then the link should include "/MAAS/docs/"
10+
11+
Scenario: It has a link to legal
12+
When the user looks for the "legal information" link
13+
Then the link should include "https://www.ubuntu.com/legal"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Feature: Images list
2+
3+
Scenario: The correct heading is rendered
4+
Given the user is logged in
5+
When the user navigates to the images page
6+
Then the main toolbar heading should be "Images"
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { Given, Then, When } from "@badeball/cypress-cucumber-preprocessor";
2+
import { generateMAASURL } from "../../../e2e/utils";
3+
4+
Given("the user is on the home page", () => {
5+
cy.visit(generateMAASURL("/"));
6+
});
7+
8+
When("the user looks for the {string} link", (linkName: string) => {
9+
cy.findByRole("link", { name: new RegExp(linkName, "i") }).as("element");
10+
});
11+
12+
Then("the link should include {string}", (expectedHref) => {
13+
cy.get("@element").should("have.attr", "href").and("include", expectedHref);
14+
});
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { Given } from "@badeball/cypress-cucumber-preprocessor";
2+
3+
Given("the user is logged in", () => {
4+
cy.login();
5+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Then, When } from "@badeball/cypress-cucumber-preprocessor";
2+
import { generateMAASURL } from "../../../e2e/utils";
3+
4+
When("the user navigates to the images page", () => {
5+
cy.visit(generateMAASURL("/images"));
6+
});
7+
8+
Then("the main toolbar heading should be {string}", (expectedHeading) => {
9+
cy.get("[data-testid='main-toolbar-heading']").should(
10+
"contain",
11+
expectedHeading
12+
);
13+
});

cypress/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"baseUrl": "../ui/node_modules",
55
"target": "es6",
66
"lib": ["es2017", "dom"],
7-
"types": ["cypress", "cypress-axe", "@testing-library/cypress", "@percy/cypress"],
7+
"types": ["node", "cypress", "cypress-axe", "@testing-library/cypress", "@percy/cypress"],
88
"moduleResolution": "Node"
99
},
1010
"include": ["**/*.ts"]

package.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@
9191
"yup": "0.32.11"
9292
},
9393
"devDependencies": {
94+
"@badeball/cypress-cucumber-preprocessor": "23.0.0",
95+
"@bahmutov/cypress-esbuild-preprocessor": "2.2.5",
9496
"@canonical/typescript-config-react": "0.9.0",
9597
"@eslint/compat": "1.4.1",
9698
"@eslint/eslintrc": "3.3.1",
@@ -119,7 +121,7 @@
119121
"@types/chance": "1.1.7",
120122
"@types/classnames": "2.3.4",
121123
"@types/clone-deep": "4.0.4",
122-
"@types/node": "22.19.1",
124+
"@types/node": "25.0.3",
123125
"@types/path-parse": "1.0.22",
124126
"@types/pluralize": "0.0.33",
125127
"@types/react": "19.2.4",
@@ -207,5 +209,8 @@
207209
"prefer-alphabetical-dependencies": "error",
208210
"prefer-alphabetical-devDependencies": "error"
209211
}
212+
},
213+
"cypress-cucumber-preprocessor": {
214+
"nonGlobalStepDefinitions": true
210215
}
211-
}
216+
}

0 commit comments

Comments
 (0)