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
5 changes: 5 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
BRIDGE_BASE_ADDRESS=https://console-openshift-console.apps.your-cluster.example.com
BRIDGE_KUBEADMIN_PASSWORD=your-password
TEST_NS=cy-test-ns
UDN_NS=udn-test-ns
HIDE_XHR=true
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ integration-tests/screenshots
integration-tests/.DS_Store
yarn-error.log
.DS_Store
cypress/gui-test-screenshots/
.env
14 changes: 14 additions & 0 deletions package-lock.json

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

13 changes: 8 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@
"start-console": "./start-console.sh",
"i18n": "./i18n-scripts/build-i18n.sh && node ./i18n-scripts/set-english-defaults.js",
"ts-node": "ts-node -O '{\"module\":\"commonjs\"}'",
"lint": "eslint ./src ./integration-tests",
"lint-fix": "eslint ./src ./integration-tests --fix",
"test-cypress": "cd integration-tests s && cypress open --env openshift=true",
"lint": "eslint ./src ./integration-tests ./ui-tests-cy",
"lint-fix": "eslint ./src ./integration-tests ./ui-tests-cy --fix",
"test-cypress": "cd integration-tests && cypress open --env openshift=true",
"test-cypress-headless": "cd integration-tests && node --max-old-space-size=4096 ../node_modules/.bin/cypress run --env openshift=true --browser ${BRIDGE_E2E_BROWSER_NAME:=electron}",
"cypress-merge": "mochawesome-merge ./integration-tests/screenshots/cypress_report*.json > ./integration-tests/screenshots/cypress.json",
"cypress-generate": "marge -o ./integration-tests/screenshots/ -f cypress-report -t 'OpenShift Console Plugin Template Cypress Test Results' -p 'OpenShift Cypress Plugin Template Test Results' --showPassed false --assetsDir ./integration-tests/screenshots/cypress/assets ./integration-tests/screenshots/cypress.json",
"test-e2e": "cd cypress && node --max-old-space-size=4096 ../node_modules/.bin/cypress run --env openshift=true --browser ${BRIDGE_E2E_BROWSER_NAME:=electron}",
"test-e2e-open": "cd cypress && cypress open --env openshift=true",
"cypress-merge": "mochawesome-merge ./cypress/gui-test-screenshots/cypress_report*.json > ./cypress/gui-test-screenshots/cypress.json",
"cypress-generate": "marge -o ./cypress/gui-test-screenshots/ -f cypress-report -t 'Networking Console Plugin Test Results' -p 'Networking Plugin Test Results' --showPassed false --assetsDir ./cypress/gui-test-screenshots/assets ./cypress/gui-test-screenshots/cypress.json",
"cypress-postreport": "npm run cypress-merge && npm run cypress-generate",
"memsource-upload": "./i18n-scripts/memsource-upload.sh",
"memsource-download": "./i18n-scripts/memsource-download.sh",
Expand Down Expand Up @@ -59,6 +61,7 @@
"css-loader": "^6.7.1",
"cypress": "^15.0.0",
"cypress-multi-reporters": "^2.0.0",
"dotenv": "^17.4.2",
"esbuild-loader": "^4.4.2",
"eslint": "^8.57.1",
"eslint-config-prettier": "^8.10.0",
Expand Down
17 changes: 17 additions & 0 deletions ui-tests-cy/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"env": {
"cypress/globals": true,
"node": true
},
"extends": ["../.eslintrc.json", "plugin:cypress/recommended"],
"plugins": ["cypress"],
"rules": {
"no-console": "off",
"no-namespace": "off",
"no-redeclare": "off",
"promise/catch-or-return": "off",
"promise/no-nesting": "off",
"@typescript-eslint/no-var-requires":"off",
"@typescript-eslint/no-namespace":"off"
}
}
31 changes: 31 additions & 0 deletions ui-tests-cy/cypress.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const { defineConfig } = require('cypress');

module.exports = defineConfig({
defaultCommandTimeout: 60000,
e2e: {
setupNodeEvents(on, config) {
return require('./plugins/index.ts')(on, config);
},
specPattern: 'tests/**/*.cy.ts',
supportFile: 'support/index.ts',
testIsolation: false,
},
fixturesFolder: false,
pageLoadTimeout: 120000,
reporter: '../node_modules/cypress-multi-reporters',
reporterOptions: {
configFile: 'reporter-config.json',
},
retries: {
openMode: 0,
runMode: 0,
},
screenshotOnRunFailure: true,
screenshotsFolder: './gui-test-screenshots/screenshots/',
trashAssetsBeforeRuns: true,
video: true,
videosFolder: './gui-test-screenshots/videos/',
viewportHeight: 1080,
viewportWidth: 1920,
watchForFileChanges: false,
});
31 changes: 31 additions & 0 deletions ui-tests-cy/plugins/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const wp = require('@cypress/webpack-preprocessor');
const path = require('path');
const dotenv = require('dotenv');

dotenv.config({ path: path.resolve(__dirname, '../../.env') });

module.exports = (on, config) => {
const options = {
webpackOptions: {
module: {
rules: [
{
exclude: /node_modules/,
loader: 'esbuild-loader',
test: /\.ts$/,
},
],
},
resolve: {
extensions: ['.ts', '.tsx', '.js'],
},
},
};
on('file:preprocessor', wp(options));
config.baseUrl = `${process.env.BRIDGE_BASE_ADDRESS || 'http://localhost:9000/'}`;
config.env.BRIDGE_KUBEADMIN_PASSWORD = process.env.BRIDGE_KUBEADMIN_PASSWORD;
config.env.TEST_NS = process.env.TEST_NS;
config.env.UDN_NS = process.env.UDN_NS;
config.env.HIDE_XHR = process.env.HIDE_XHR;
return config;
};
14 changes: 14 additions & 0 deletions ui-tests-cy/reporter-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"reporterEnabled": "mocha-junit-reporter, mochawesome",
"mochaJunitReporterReporterOptions": {
"mochaFile": "./gui-test-screenshots/junit_cypress-[hash].xml",
"toConsole": false
},
"mochawesomeReporterOptions": {
"reportDir": "./gui-test-screenshots/",
"reportFilename": "cypress_report",
"overwrite": false,
"html": true,
"json": true
}
}
45 changes: 45 additions & 0 deletions ui-tests-cy/support/commands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { MINUTE, SECOND } from '../utils/const/base';

declare global {
namespace Cypress {
interface Chainable {
deleteResource(kind: string, name: string, namespace?: string): void;
switchProject(projectName: string): void;
}
}
}

Cypress.Commands.add('deleteResource', (kind: string, name: string, namespace?: string) => {
const args = ['oc', 'delete', '--ignore-not-found=true'];
if (namespace) {
args.push('-n', namespace);
}
args.push(kind, name, '--wait=true', '--timeout=300s');
cy.exec(args.join(' '), { failOnNonZeroExit: false, timeout: 5 * MINUTE });
});

Cypress.Commands.add('switchProject', (projectName: string) => {
cy.byLegacyTestID('namespace-bar-dropdown').contains('Project:').click();
if (projectName === 'All Projects') {
cy.contains('All Projects').click();
return;
}
cy.get('body').then(($body) => {
if ($body.find('[data-test="showSystemSwitch"]').length) {
cy.byTestID('showSystemSwitch').check();
cy.wait(3 * SECOND);
}
});
cy.get(
'input[data-test="dropdown-text-filter"], input[placeholder*="name"], input[aria-label*="filter"]',
{ timeout: 10000 },
)
.first()
.then(($input) => {
cy.wrap($input).clear();
cy.wrap($input).type(projectName);
});
cy.contains('[data-test="dropdown-menu-item-link"], [role="option"], button', projectName, {
timeout: 10000,
}).click();
});
20 changes: 20 additions & 0 deletions ui-tests-cy/support/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import './login';
import './selectors';
import './commands';
import './nav';

Cypress.on('uncaught:exception', (err) => {
if (err.message.includes('ResizeObserver') || err.message.includes('Script error')) {
return false;
}
});

if (Cypress.env('HIDE_XHR')) {
const origLog = Cypress.log;
Cypress.log = function (opts, ...other) {
if (opts.displayName === 'fetch' || opts.displayName === 'xhr') {
return;
}
return origLog(opts, ...other);
};
}
60 changes: 60 additions & 0 deletions ui-tests-cy/support/login.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { MINUTE } from '../utils/const/base';

const KUBEADMIN_USERNAME = 'kubeadmin';
const KUBEADMIN_IDP = 'kube:admin';
const TOUR_DISMISS = '[data-test="tour-step-footer-secondary"]';

declare global {
namespace Cypress {
interface Chainable {
login(providerName?: string, username?: string, password?: string): Chainable<Element>;
logout(): void;
}
}
}

Cypress.Commands.add('login', (provider: string, username: string, password: string) => {
const usr = username || KUBEADMIN_USERNAME;
const pwd = password || Cypress.env('BRIDGE_KUBEADMIN_PASSWORD');
const idp = provider || KUBEADMIN_IDP;

cy.visit('');

cy.origin(
Cypress.config('baseUrl').replace('console-openshift-console', 'oauth-openshift'),
{ args: { idp, pwd, usr } },
({ idp: originIdp, pwd: originPwd, usr: originUsr }) => {
// Wait for either the login form or IDP selection page
cy.get('body', { timeout: 180000 }).should('be.visible');
cy.get('body').then(($body) => {
if ($body.find('#inputUsername').length === 0) {
// IDP selection page — click the matching provider
if ($body.text().includes(originIdp)) {
cy.contains('a', originIdp).click();
} else if ($body.text().includes('kubeadmin')) {
cy.contains('a', 'kubeadmin').click();
} else {
cy.get('a').first().click();
}
}
});
cy.get('#inputUsername', { timeout: 180000 }).should('be.visible');
cy.get('#inputUsername').type(originUsr);
cy.get('#inputPassword').type(originPwd, { log: false });
cy.get('button[type=submit]').click();
},
);

cy.url({ timeout: 2 * MINUTE }).should('include', 'console-openshift-console');
cy.get('body').then(($body) => {
if ($body.find(TOUR_DISMISS).length) {
cy.get(TOUR_DISMISS).click();
}
});
});

Cypress.Commands.add('logout', () => {
cy.get('[data-test="user-dropdown"]').click();
cy.get('[data-test="log-out"]').should('be.visible');
cy.get('[data-test="log-out"]').click({ force: true });
});
28 changes: 28 additions & 0 deletions ui-tests-cy/support/nav.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { MINUTE } from '../utils/const/base';

declare global {
namespace Cypress {
interface Chainable {
visitNAD(): void;
visitService(): void;
visitUDN(): void;
}
}
}

Cypress.Commands.add('visitNAD', () => {
const ns = Cypress.env('TEST_NS') || 'cy-test-ns';
cy.visit(`/k8s/ns/${ns}/k8s.cni.cncf.io~v1~NetworkAttachmentDefinition`);
cy.checkTitle('NetworkAttachmentDefinitions', MINUTE);
});

Cypress.Commands.add('visitUDN', () => {
cy.visit('/k8s/all-namespaces/k8s.ovn.org~v1~UserDefinedNetwork');
cy.checkTitle('UserDefinedNetworks', MINUTE);
cy.byButtonText('Create').should('be.visible');
});

Cypress.Commands.add('visitService', () => {
cy.visit('/k8s/all-namespaces/services');
cy.checkTitle('Services', MINUTE);
});
Loading