diff --git a/cypress/e2e/po/pages/about.po.ts b/cypress/e2e/po/pages/about.po.ts new file mode 100644 index 00000000000..84df525aa24 --- /dev/null +++ b/cypress/e2e/po/pages/about.po.ts @@ -0,0 +1,55 @@ +import PagePo from '@/cypress/e2e/po/pages/page.po'; +import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po'; + +const burgerMenu = new BurgerMenuPo(); + +/** + * About page + */ +export default class AboutPagePo extends PagePo { + static url = '/about' + static goTo(): Cypress.Chainable { + return super.goTo(AboutPagePo.url); + } + + constructor() { + super(AboutPagePo.url); + } + + static navTo() { + burgerMenu.about().click(); + } + + diagnosticsBtn() { + return cy.getId('about__diagnostics_button'); + } + + links(value: string): Cypress.Chainable { + return this.self().get('.about').find('a').contains(value); + } + + getLinkDestination(value: string): Cypress.Chainable { + return this.links(value).invoke('prop', 'href'); + } + + clickVersionLink(value: string) { + this.links(value) + .then((el) => { + expect(el).to.have.attr('target'); + }) + .invoke('removeAttr', 'target') + .click(); + } + + getLinuxDownloadLink() { + return cy.getId('image_list_download_link__about.os.linux'); + } + + getWindowsDownloadLink() { + return cy.getId('image_list_download_link__about.os.windows'); + } + + getCliDownloadLinkByLabel(label: string) { + return this.self().contains(label); + } +} diff --git a/cypress/e2e/po/side-bars/burger-side-menu.po.ts b/cypress/e2e/po/side-bars/burger-side-menu.po.ts index ca3623c4155..d23463053ab 100644 --- a/cypress/e2e/po/side-bars/burger-side-menu.po.ts +++ b/cypress/e2e/po/side-bars/burger-side-menu.po.ts @@ -114,4 +114,12 @@ export default class BurgerMenuPo extends ComponentPo { home(): Cypress.Chainable { return this.self().find('.body > div > a').first(); } + + /** + * Get the About link + * @returns {Cypress.Chainable} + */ + about(): Cypress.Chainable { + return this.self().contains('About'); + } } diff --git a/cypress/e2e/tests/pages/about.spec.ts b/cypress/e2e/tests/pages/about.spec.ts new file mode 100644 index 00000000000..0c7f8b44796 --- /dev/null +++ b/cypress/e2e/tests/pages/about.spec.ts @@ -0,0 +1,162 @@ +import HomePagePo from '@/cypress/e2e/po/pages/home.po'; +import AboutPagePo from '@/cypress/e2e/po/pages/about.po'; +import DiagnosticsPagePo from '@/cypress/e2e/po/pages/diagnostics.po'; +import * as path from 'path'; + +const aboutPage = new AboutPagePo(); +const downloadsFolder = Cypress.config('downloadsFolder'); + +describe('About Page', { testIsolation: 'off', tags: ['@adminUser', '@standardUser'] }, () => { + before(() => { + cy.login(); + }); + + it('can navigate to About page', () => { + HomePagePo.goToAndWaitForGet(); + AboutPagePo.navTo(); + aboutPage.waitForPage(); + }); + + it('can navigate to Diagnostics page', () => { + AboutPagePo.navTo(); + aboutPage.waitForPage(); + aboutPage.diagnosticsBtn().click(); + + const diagnosticsPo = new DiagnosticsPagePo(); + + diagnosticsPo.waitForPage(); + }); + + it('can View release notes', () => { + AboutPagePo.navTo(); + aboutPage.waitForPage(); + + aboutPage.clickVersionLink('View release notes'); + cy.origin('https://github.com/rancher/rancher', () => { + cy.url().should('include', 'https://github.com/rancher/rancher/releases/tag/'); + }); + }); + + describe('Versions', () => { + beforeEach(() => { + aboutPage.goTo(); + }); + + it('can see rancher version', () => { + // Check Rancher version + cy.getRancherResource('v1', 'management.cattle.io.settings', 'server-version').then((resp: Cypress.Response) => { + const rancherVersion = resp.body['value']; + + cy.contains(rancherVersion).should('be.visible'); + }); + }); + + it('can navigate to /rancher/rancher', () => { + aboutPage.clickVersionLink('Rancher'); + cy.origin('https://github.com/rancher/rancher', () => { + cy.url().should('include', 'https://github.com/rancher/rancher'); + }); + }); + + it('can navigate to /rancher/dashboard', () => { + aboutPage.clickVersionLink('Dashboard'); + cy.origin('https://github.com/rancher/dashboard', () => { + cy.url().should('include', 'https://github.com/rancher/dashboard'); + }); + }); + + it('can navigate to /rancher/helm', () => { + aboutPage.clickVersionLink('Helm'); + cy.origin('https://github.com/rancher/helm', () => { + cy.url().should('include', 'https://github.com/rancher/helm'); + }); + }); + + it('can navigate to /rancher/machine', () => { + aboutPage.clickVersionLink('Machine'); + cy.origin('https://github.com/rancher/machine', () => { + cy.url().should('include', 'https://github.com/rancher/machine'); + }); + }); + }); + + describe('Image List', () => { + before(() => { + aboutPage.goTo(); + }); + + it('can download Linux Image List', () => { + // Download txt and verify file exists + const downloadedFilename = path.join(downloadsFolder, 'rancher-linux-images.txt'); + + aboutPage.getLinuxDownloadLink().click(); + + cy.getRancherResource('v1', 'management.cattle.io.settings', 'server-version').then((resp: Cypress.Response) => { + const rancherVersion = resp.body['value']; + + cy.readFile(downloadedFilename).should('contain', rancherVersion); + }); + }); + + it('can download Windows Image List', () => { + const downloadedFilename = path.join(downloadsFolder, 'rancher-windows-images.txt'); + + aboutPage.getWindowsDownloadLink().click(); + cy.getRancherResource('v1', 'management.cattle.io.settings', 'server-version').then((resp: Cypress.Response) => { + const rancherVersion = resp.body['value']; + + cy.readFile(downloadedFilename).should('contain', rancherVersion); + }); + }); + }); + + describe('CLI Downloads', () => { + // workaround to make the following CLI tests work https://github.com/cypress-io/cypress/issues/8089#issuecomment-1585159023 + beforeEach(() => { + aboutPage.goTo(); + cy.intercept('GET', 'https://releases.rancher.com/cli2/**').as('download'); + }); + + it('can download macOS CLI', () => { + aboutPage.getLinkDestination('rancher-darwin').then((el) => { + const macOsVersion = el.split('/')[5]; + + aboutPage.getCliDownloadLinkByLabel('rancher-darwin').then((el: any) => { + el.attr('download', ''); + }).click(); + cy.wait('@download').then(({ request, response }) => { + expect(response?.statusCode).to.eq(200); + expect(request.url).includes(macOsVersion); + }); + }); + }); + + it('can download Linux CLI', () => { + aboutPage.getLinkDestination('rancher-linux').then((el) => { + const linuxVersion = el.split('/')[5]; + + aboutPage.getCliDownloadLinkByLabel('rancher-linux').then((el: any) => { + el.attr('download', ''); + }).click(); + cy.wait('@download').then(({ request, response }) => { + expect(response?.statusCode).to.eq(200); + expect(request.url).includes(linuxVersion); + }); + }); + }); + + it('can download Windows CLI', () => { + aboutPage.getLinkDestination('rancher-windows').then((el) => { + const windowsVersion = el.split('/')[5]; + + aboutPage.getCliDownloadLinkByLabel('rancher-windows').then((el: any) => { + el.attr('download', ''); + }).click(); + cy.wait('@download').then(({ request, response }) => { + expect(response?.statusCode).to.eq(200); + expect(request.url).includes(windowsVersion); + }); + }); + }); + }); +}); diff --git a/cypress/e2e/tests/pages/home.spec.ts b/cypress/e2e/tests/pages/home.spec.ts index b76c39a3633..3bdf184ddb1 100644 --- a/cypress/e2e/tests/pages/home.spec.ts +++ b/cypress/e2e/tests/pages/home.spec.ts @@ -179,7 +179,6 @@ describe('Home Page', () => { it('can click on Forums link', () => { // click Forums link - HomePagePo.goTo(); homePage.clickSupportLink(1, true); cy.origin('https://forums.rancher.com', () => { cy.url().should('include', 'forums.rancher.com/'); @@ -188,7 +187,6 @@ describe('Home Page', () => { it('can click on Slack link', () => { // click Slack link - HomePagePo.goTo(); homePage.clickSupportLink(2, true); cy.origin('https://slack.rancher.io', () => { cy.url().should('include', 'slack.rancher.io/'); diff --git a/cypress/globals.d.ts b/cypress/globals.d.ts index abe7555deb6..92ccf7b3088 100644 --- a/cypress/globals.d.ts +++ b/cypress/globals.d.ts @@ -37,6 +37,7 @@ declare namespace Cypress { getRancherResource(prefix: 'v3' | 'v1', resourceType: string, resourceId: string, expectedStatusCode: string): Chainable; setRancherResource(prefix: 'v3' | 'v1', resourceType: string, resourceId: string, body: string): Chainable; + getUserPreferences(): Chainable; /** * Wrapper for cy.get() to simply define the data-testid value that allows you to pass a matcher to find the element. diff --git a/shell/pages/about.vue b/shell/pages/about.vue index 4b559c99896..c2cc92ece99 100644 --- a/shell/pages/about.vue +++ b/shell/pages/about.vue @@ -101,6 +101,7 @@ export default { {{ t('about.diagnostic.title') }} @@ -195,6 +196,7 @@ export default { {{ t('asyncButton.download.action') }}