Skip to content

Commit

Permalink
Merge pull request #11508 from aalves08/11482-extensions-compatibilit…
Browse files Browse the repository at this point in the history
…y-tests

Extensions compatibility tests 2.10
  • Loading branch information
richard-cox authored Aug 15, 2024
2 parents eacc68f + c15a3a1 commit 5ee4809
Show file tree
Hide file tree
Showing 14 changed files with 484 additions and 8 deletions.
66 changes: 66 additions & 0 deletions .github/workflows/extensions-compatibility-tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: Extensions Compatibility Tests
on:
schedule:
- cron: "0 0 * * *" # runs at midnight every day

env:
TEST_USERNAME: admin
TEST_PASSWORD: password
CATTLE_BOOTSTRAP_PASSWORD: password
TEST_BASE_URL: https://127.0.0.1:8005
API: https://127.0.0.1
TEST_PROJECT_ID: rancher-dashboard
CYPRESS_API_URL: http://139.59.134.103:1234/
TEST_RUN_ID: ${{github.run_number}}-${{github.run_attempt}}-extensions-compatibility-tests

jobs:
e2e-test-extensions-compatibility:
strategy:
fail-fast: false
matrix:
role: [
{ username: 'admin', tag: '@adminUser' }
]
features: [
['@elemental', 'elemental']
]
rancherEnv: [
['2.10', 'v2.9-head'],
# ['2.9', 'v2.9-head']
]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 1
- name: Setup env
uses: ./.github/actions/setup

# this is where docker is set up with the enviroment
- name: Run Rancher system ${{ matrix.rancherEnv[0] }} - image:${{ matrix.rancherEnv[1] }}
run: export RANCHER_VERSION_E2E=${{ matrix.rancherEnv[1] }} && yarn e2e:docker

## this is just setting up rancher and user
- name: Setup Rancher and user
run: |
yarn e2e:prod
env:
GREP_TAGS: ${{ matrix.role.tag }}Setup+${{ matrix.features[0] }} --@jenkins ${{ matrix.role.tag }}Setup+${{ matrix.features[0] }} --@jenkins
TEST_USERNAME: ${{ matrix.role.username }}
TEST_ONLY: setup

# This is the actual triggering of the e2e test specs
- name: Run user tests
run: |
export SPEC_FILE="cypress/e2e/tests/extensions/${{ matrix.features[1] }}/${{ matrix.features[1] }}.spec.ts" && yarn e2e:prod
env:
TEST_SKIP: setup
GREP_TAGS: ${{ matrix.role.tag }}+${{ matrix.features[0] }} --@jenkins ${{ matrix.role.tag }}+${{ matrix.features[0] }} --@jenkins
TEST_USERNAME: ${{ matrix.role.username }}

- name: Upload screenshots
uses: actions/upload-artifact@v3
if: ${{ failure() }}
with:
name: ${{github.run_number}}-${{github.run_attempt}}-extensions-compatibility-tests-screenshots-${{ matrix.role.tag }}+${{ matrix.features[0] }}
path: cypress/screenshots
2 changes: 1 addition & 1 deletion cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require('dotenv').config();
* VARIABLES
*/
const hasCoverage = (process.env.TEST_INSTRUMENT === 'true') || false; // Add coverage if instrumented
const testDirs = ['priority', 'components', 'setup', 'pages', 'navigation', 'global-ui', 'features'];
const testDirs = ['priority', 'components', 'setup', 'pages', 'navigation', 'global-ui', 'features', 'extensions'];
const skipSetup = process.env.TEST_SKIP?.includes('setup');
const baseUrl = (process.env.TEST_BASE_URL || 'https://localhost:8005').replace(/\/$/, '');
const DEFAULT_USERNAME = 'admin';
Expand Down
6 changes: 6 additions & 0 deletions cypress/e2e/po/components/labeled-select.po.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ export default class LabeledSelectPo extends ComponentPo {
return this.self().click();
}

setOptionAndClick(label: string) {
this.self().get('input[type="search"]').type(label);

return this.clickOption(1);
}

clickOption(optionIndex: number) {
return this.self().get(`.vs__dropdown-menu .vs__dropdown-option:nth-child(${ optionIndex })`).click();
}
Expand Down
5 changes: 5 additions & 0 deletions cypress/e2e/po/components/resource-yaml.po.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import ComponentPo from '@/cypress/e2e/po/components/component.po';
import { CypressChainable } from '@/cypress/e2e/po/po.types';
import AsyncButtonPo from '@/cypress/e2e/po/components/async-button.po';
import CodeMirrorPo from '@/cypress/e2e/po/components/code-mirror.po';

export default class ResourceYamlPo extends ComponentPo {
constructor(parent?: CypressChainable) {
Expand All @@ -15,6 +16,10 @@ export default class ResourceYamlPo extends ComponentPo {
return this.self().find('.footer');
}

codeMirror() {
return CodeMirrorPo.bySelector(this.self(), '[data-testid="yaml-editor-code-mirror"]');
}

saveOrCreate(): AsyncButtonPo {
return new AsyncButtonPo('[data-testid="action-button-async-button"]', this.self());
}
Expand Down
47 changes: 47 additions & 0 deletions cypress/e2e/po/extensions/elemental/elemental.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import ExtensionsCompatibilityUtils from '~/cypress/e2e/po/extensions/extensions-compatibility.utils';
import BannersPo from '@/cypress/e2e/po/components/banners.po';
import LabeledSelectPo from '@/cypress/e2e/po/components/labeled-select.po';
import RadioGroupInputPo from '@/cypress/e2e/po/components/radio-group-input.po';
import PagePo from '@/cypress/e2e/po/pages/page.po';

class DashboardPagePo extends PagePo {
private static url = '/elemental/c/_/dashboard';

constructor() {
super(DashboardPagePo.url);
}

waitForTitle(): Cypress.Chainable {
return this.self().find('h1').should('contain', 'OS Management');
}

installOperator(): Cypress.Chainable {
return this.self().getId('charts-install-button').click();
}

createElementalCluster() {
return this.self().getId('button-create-elemental-cluster').click();
}

createUpdateGroupClick() {
return this.self().getId('create-update-group-btn').click();
}
}

export default class ElementalPo extends ExtensionsCompatibilityUtils {
dashboard() {
return new DashboardPagePo();
}

elementalClusterSelectorTemplateBanner() {
return new BannersPo('[provider="machineinventoryselectortemplate"] .banner.warning');
}

updateGroupTargetClustersSelect() {
return new LabeledSelectPo('[data-testid="cluster-target"]');
}

updateGroupImageOption() {
return new RadioGroupInputPo('[data-testid="upgrade-choice-selector"]');
}
}
41 changes: 41 additions & 0 deletions cypress/e2e/po/extensions/extensions-compatibility.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
import { InstallChartPage } from '@/cypress/e2e/po/pages/explorer/charts/install-charts.po';
import ChartInstalledAppsPagePo from '@/cypress/e2e/po/pages/chart-installed-apps.po';
import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
import NameNsDescriptionPo from '@/cypress/e2e/po/components/name-ns-description.po';
import ResourceDetailPo from '@/cypress/e2e/po/edit/resource-detail.po';
import CodeMirrorPo from '~/cypress/e2e/po/components/code-mirror.po';

const installChartPage = new InstallChartPage();
const appsPage = new ChartInstalledAppsPagePo('local', 'apps');
const root = '.dashboard-root';

export default class ExtensionsCompatibilityUtils {
appsPage() {
return appsPage;
}

chartInstallPage() {
return installChartPage;
}

genericPage(path: string) {
return new PagePo(path);
}

genericResourceList(): BaseResourceList {
return new BaseResourceList(cy.get(root));
}

genericNameNsDescription(): NameNsDescriptionPo {
return new NameNsDescriptionPo(cy.get(root));
}

genericResourceDetail() {
return new ResourceDetailPo(cy.get(root));
}

genericCodeMirror() {
return CodeMirrorPo.bySelector(cy.get(root), '[data-testid="yaml-editor-code-mirror"]');
}
}
19 changes: 19 additions & 0 deletions cypress/e2e/po/pages/chart-installed-apps.po.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
import ChartInstalledAppsListPo from '@/cypress/e2e/po/lists/chart-installed-apps.po';
import Kubectl from '@/cypress/e2e/po/components/kubectl.po';

const terminal = new Kubectl();

/**
* List page for catalog.cattle.io.app resources
Expand All @@ -24,4 +27,20 @@ export default class ChartInstalledAppsPagePo extends PagePo {
list(): ChartInstalledAppsListPo {
return new ChartInstalledAppsListPo('[data-testid="installed-app-catalog-list"]');
}

waitForInstallCloseTerminal(interceptName: string, installableParts: Array<String>) {
cy.wait(`@${ interceptName }`, { requestTimeout: 20000 }).its('response.statusCode').should('eq', 201);

// giving it a small buffer so that the install is properly triggered
cy.wait(15000); // eslint-disable-line cypress/no-unnecessary-waiting
terminal.closeTerminal();

installableParts.forEach((item:string) => {
this.list().state(item).should('contain', 'Deployed');
});

// timeout to give time for everything to be setup, otherwise the extension
// won't find the chart and show the correct screen
return cy.wait(10000); // eslint-disable-line cypress/no-unnecessary-waiting
}
}
38 changes: 38 additions & 0 deletions cypress/e2e/po/pages/extensions.po.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import NameNsDescriptionPo from '@/cypress/e2e/po/components/name-ns-description
import RepositoriesPagePo from '@/cypress/e2e/po/pages/chart-repositories.po';
import BannersPo from '@/cypress/e2e/po/components/banners.po';
import ChartRepositoriesCreateEditPo from '@/cypress/e2e/po/edit/chart-repositories.po';
import AppClusterRepoEditPo from '@/cypress/e2e/po/edit/catalog.cattle.io.clusterrepo.po';
import { LONG_TIMEOUT_OPT } from '@/cypress/support/utils/timeouts';

export default class ExtensionsPagePo extends PagePo {
Expand Down Expand Up @@ -83,6 +84,35 @@ export default class ExtensionsPagePo extends PagePo {
appRepoList.list().state(name).should('contain', 'Active');
}

/**
* Adds a cluster repo for extensions
* @param repo - The repository url (e.g. https://github.com/rancher/ui-plugin-examples)
* @param branch - The git branch to target
* @param name - A name for the repository
* @returns {Cypress.Chainable}
*/
addExtensionsRepositoryDirectLink(repo: string, branch: string, name: string, waitForActiveState = true): Cypress.Chainable {
const appRepoList = new RepositoriesPagePo('local', 'apps');
const appRepoCreate = new AppClusterRepoEditPo('local', 'create');

appRepoCreate.goTo();
appRepoCreate.waitForPage();

appRepoCreate.nameNsDescription().name().self().scrollIntoView()
.should('be.visible');
appRepoCreate.nameNsDescription().name().set(name);
appRepoCreate.selectRadioOptionGitRepo(1);
// fill the git repo form
appRepoCreate.enterGitRepoName(repo);
appRepoCreate.enterGitBranchName(branch);
appRepoCreate.create().click();

if (waitForActiveState) {
appRepoList.waitForPage();
appRepoList.list().state(name).should('contain', 'Active');
}
}

// ------------------ extension card ------------------
extensionCard(extensionName: string) {
return this.self().getId(`extension-card-${ extensionName }`);
Expand Down Expand Up @@ -113,6 +143,14 @@ export default class ExtensionsPagePo extends PagePo {
return this.self().get('[data-modal="installPluginDialog"]');
}

installModalSelectVersionLabel(label: string): Cypress.Chainable {
const selectVersion = new LabeledSelectPo(this.extensionInstallModal().getId('install-ext-modal-select-version'));

selectVersion.toggle();

return selectVersion.setOptionAndClick(label);
}

installModalSelectVersionClick(optionIndex: number): Cypress.Chainable {
const selectVersion = new LabeledSelectPo(this.extensionInstallModal().getId('install-ext-modal-select-version'));

Expand Down
4 changes: 4 additions & 0 deletions cypress/e2e/po/pages/page.po.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ export default class PagePo extends ComponentPo {
return this.self().find('.primaryheader h1').invoke('text');
}

waitForMastheadTitle(title: string) {
return this.mastheadTitle().should('contain', title);
}

navToMenuEntry(label: string) {
BurgerMenuPo.toggle();
BurgerMenuPo.burgerMenuNavToMenubyLabel(label);
Expand Down
Loading

0 comments on commit 5ee4809

Please sign in to comment.