From 82129880bb2d04e39ecbaf1836fa0bafbb8e558e Mon Sep 17 00:00:00 2001 From: Russell Vinegar Date: Wed, 7 Aug 2024 14:47:57 -0700 Subject: [PATCH 01/21] no need for gwa-cli in 01/01 --- e2e/cypress/tests/01-api-key/01-create-api.cy.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/e2e/cypress/tests/01-api-key/01-create-api.cy.ts b/e2e/cypress/tests/01-api-key/01-create-api.cy.ts index 1c29bfbad..c6c8dfde8 100644 --- a/e2e/cypress/tests/01-api-key/01-create-api.cy.ts +++ b/e2e/cypress/tests/01-api-key/01-create-api.cy.ts @@ -65,13 +65,6 @@ describe('Create API Spec', () => { }) }) - // TODO: Update this test to use gwa cli (if not covered in other tests) - // it('Verify for invalid namespace name', () => { - // cy.get('@apiowner').then(({ invalid_namespace }: any) => { - // home.validateNamespaceName(invalid_namespace) - // }) - // }) - it('creates a new service account', () => { cy.visit(sa.path) cy.get('@apiowner').then(({ serviceAccount }: any) => { From c9c178688edbf521693eda7254fd1eba17496736 Mon Sep 17 00:00:00 2001 From: Russell Vinegar Date: Fri, 9 Aug 2024 13:43:38 -0700 Subject: [PATCH 02/21] test service name unavailable --- e2e/cypress/fixtures/common-testdata.json | 3 + e2e/cypress/fixtures/service-availability.yml | 19 +++++ e2e/cypress/support/auth-commands.ts | 18 ++--- e2e/cypress/tests/19-api-v3/07-endpoints.ts | 78 ++++++++++++++++++- 4 files changed, 108 insertions(+), 10 deletions(-) create mode 100644 e2e/cypress/fixtures/service-availability.yml diff --git a/e2e/cypress/fixtures/common-testdata.json b/e2e/cypress/fixtures/common-testdata.json index f3c7cf668..6b188709c 100644 --- a/e2e/cypress/fixtures/common-testdata.json +++ b/e2e/cypress/fixtures/common-testdata.json @@ -81,5 +81,8 @@ }, "twoTieredHidden": { "namespace": "two-tier-hidden" + }, + "serviceAvailability": { + "namespace": "service-avail" } } \ No newline at end of file diff --git a/e2e/cypress/fixtures/service-availability.yml b/e2e/cypress/fixtures/service-availability.yml new file mode 100644 index 000000000..64851f962 --- /dev/null +++ b/e2e/cypress/fixtures/service-availability.yml @@ -0,0 +1,19 @@ +kind: GatewayService +name: taken-service-name +host: httpbin.org +tags: [ns.service-avail] +port: 446 +protocol: https +retries: 0 +routes: + - name: taken-service-name + tags: [ns.service-avail] + hosts: + - taken-service-name.api.gov.bc.ca + paths: + - / + methods: + - GET + strip_path: false + https_redirect_status_code: 426 + path_handling: v0 diff --git a/e2e/cypress/support/auth-commands.ts b/e2e/cypress/support/auth-commands.ts index 2c52f515f..a415adcb1 100644 --- a/e2e/cypress/support/auth-commands.ts +++ b/e2e/cypress/support/auth-commands.ts @@ -219,16 +219,16 @@ Cypress.Commands.add( cy.fixture('apiowner').as('apiowner') cy.preserveCookies() cy.visit(login.path) - cy.interceptUserSession().then(() => { - cy.get('@apiowner').then(({ user }: any) => { - cy.login(user.credentials.username, user.credentials.password) - cy.log('Logged in!') - // cy.activateGateway(apiTest.namespace) - if (isNamespaceSelected || undefined) { - cy.activateGateway(namespace) - } + cy.get('@apiowner').then(({ user }: any) => { + cy.login(user.credentials.username, user.credentials.password) + cy.log('Logged in!') + // cy.activateGateway(apiTest.namespace) + if (isNamespaceSelected || undefined) { + cy.activateGateway(namespace) + } + cy.getUserSession().then(() => { cy.get('@login').then(function (xhr: any) { - userSession = xhr.response.headers['x-auth-request-access-token'] + userSession = xhr.headers['x-auth-request-access-token'] return userSession }) }) diff --git a/e2e/cypress/tests/19-api-v3/07-endpoints.ts b/e2e/cypress/tests/19-api-v3/07-endpoints.ts index 469887276..c2e8d47e8 100644 --- a/e2e/cypress/tests/19-api-v3/07-endpoints.ts +++ b/e2e/cypress/tests/19-api-v3/07-endpoints.ts @@ -1,4 +1,4 @@ -describe('Endpoints', () => { +describe('Endpoints - unused service', () => { it('GET /routes/availability', () => { cy.callAPI( 'ds/api/v3/routes/availability?gatewayId=gw-1234&serviceName=testme', @@ -23,3 +23,79 @@ describe('Endpoints', () => { }) }) }) + +describe('Endpoints - used service', () => { + let userSession: any + + beforeEach(() => { + cy.fixture('common-testdata').as('common-testdata') + }) + + it('authenticates Janis (api owner) to get the user session token', () => { + cy.get('@common-testdata').then(({ serviceAvailability }: any) => { + cy.getUserSessionTokenValue(serviceAvailability.namespace, false).then((value) => { + console.log(value) + userSession = value + }) + }) + }) + + it('Check gwa config command to set environment', () => { + var cleanedUrl = Cypress.env('BASE_URL').replace(/^http?:\/\//i, '') + cy.executeCliCommand('gwa config set --host ' + cleanedUrl + ' --scheme http').then( + (response) => { + expect(response.stdout).to.contain('Config settings saved') + } + ) + }) + + it('Check gwa config command to set token', () => { + cy.executeCliCommand('gwa config set --token ' + userSession).then((response) => { + expect(response.stdout).to.contain('Config settings saved') + }) + }) + + it('create namespace with cli', () => { + cy.get('@common-testdata').then(({ serviceAvailability }: any) => { + cy.executeCliCommand( + 'gwa gateway create --gateway-id ' + serviceAvailability.namespace + ' --display-name="Service Availability"' + ).then((response) => { + expect(response.stdout).to.contain(serviceAvailability.namespace) + }) + }) + }) + + it('Upload config for key-auth', () => { + cy.executeCliCommand('gwa apply -i ./cypress/fixtures/service-availability.yml').then((response) => { + expect(response.stdout).to.contain('Gateway Services published'); + }) + }) + + it('GET /routes/availability', () => { + cy.callAPI( + 'ds/api/v3/routes/availability?gatewayId=gw-1234&serviceName=taken-service-name', + 'GET' + ).then(({ apiRes: { status, body } }: any) => { + const match = { + available: false, + suggestion: { + serviceName: "gw-1234-taken-service-name", + names: [ + "gw-1234-taken-service-name", + "gw-1234-taken-service-name-dev", + "gw-1234-taken-service-name-test" + ], + hosts: [ + "gw-1234-taken-service-name.api.gov.bc.ca", + "gw-1234-taken-service-name.dev.api.gov.bc.ca", + "gw-1234-taken-service-name.test.api.gov.bc.ca", + "gw-1234-taken-service-name-api-gov-bc-ca.dev.api.gov.bc.ca", + "gw-1234-taken-service-name-api-gov-bc-ca.test.api.gov.bc.ca" + ] + }, + } + expect(status).to.be.equal(200) + expect(JSON.stringify(body)).to.be.equal(JSON.stringify(match)) + }) + }) +}) \ No newline at end of file From 25075ed70fab5bc025e6aba3d3aa21d253688655 Mon Sep 17 00:00:00 2001 From: Russell Vinegar Date: Fri, 9 Aug 2024 15:10:50 -0700 Subject: [PATCH 03/21] add test for org/publishing status --- e2e/cypress/pageObjects/namespace.ts | 1 + .../01-client-cred-team-access.ts | 17 +++++++++++++++++ src/nextapp/pages/manager/gateways/list.tsx | 1 + 3 files changed, 19 insertions(+) diff --git a/e2e/cypress/pageObjects/namespace.ts b/e2e/cypress/pageObjects/namespace.ts index b38b5227b..d5f1c7ee8 100644 --- a/e2e/cypress/pageObjects/namespace.ts +++ b/e2e/cypress/pageObjects/namespace.ts @@ -1,5 +1,6 @@ class NameSpacePage { path: string = '/manager/gateways' + listPath: string = 'manager/gateways/list' detailPath: string = '/manager/gateways/detail' gatewayServiceLink: string = '[data-testid="ns-manage-link-Gateway Services"]' productsLink: string = '[data-testid="ns-manage-link-Gateway Services"]' diff --git a/e2e/cypress/tests/14-org-assignment/01-client-cred-team-access.ts b/e2e/cypress/tests/14-org-assignment/01-client-cred-team-access.ts index 4e8e5fcf7..5511ff260 100644 --- a/e2e/cypress/tests/14-org-assignment/01-client-cred-team-access.ts +++ b/e2e/cypress/tests/14-org-assignment/01-client-cred-team-access.ts @@ -15,6 +15,7 @@ describe('Add Organization to publish API', () => { const login = new LoginPage() const home = new HomePage() const na = new NamespaceAccessPage() + const ns = new NameSpacePage() const pd = new Products() const sa = new ServiceAccountsPage() const apiDir = new ApiDirectoryPage() @@ -114,6 +115,11 @@ describe('Add Organization to publish API', () => { }) }) + it('Verify My Gateways shows publishing "disabled"', () => { + cy.visit(ns.listPath) + cy.get(`[data-testid="ns-list-item-${namespace}"]`).should('contain.text', 'Publishing disabled') + }) + it('Assign organization to the created namespace', () => { cy.visit(apiDir.path) cy.get('@apiowner').then(({ product }: any) => { @@ -121,6 +127,11 @@ describe('Add Organization to publish API', () => { }) }) + it('Verify My Gateways shows publishing "pending"', () => { + cy.visit(ns.listPath) + cy.get(`[data-testid="ns-list-item-${namespace}"]`).should('contain.text', 'Pending publishing permission') + }) + it('Verify Organization Administrator notification banner', () => { cy.visit(apiDir.path) cy.get('@apiowner').then(({ orgAssignment }: any) => { @@ -182,6 +193,7 @@ describe('Org Admin approves the request', () => { describe('Activate the API to make it visible in API Directory', () => { const login = new LoginPage() const home = new HomePage() + const ns = new NameSpacePage() const pd = new Products() const apiDir = new ApiDirectoryPage() @@ -203,6 +215,11 @@ describe('Activate the API to make it visible in API Directory', () => { }) }) + it('Verify My Gateways shows publishing "enabled"', () => { + cy.visit(ns.listPath) + cy.get(`[data-testid="ns-list-item-${namespace}"]`).should('contain.text', 'Publishing enabled') + }) + it('update the Dataset in BC Data Catelogue to appear the API in the Directory', () => { cy.visit(pd.path) cy.get('@apiowner').then(({ orgAssignment }: any) => { diff --git a/src/nextapp/pages/manager/gateways/list.tsx b/src/nextapp/pages/manager/gateways/list.tsx index 28ae4e640..a09125816 100644 --- a/src/nextapp/pages/manager/gateways/list.tsx +++ b/src/nextapp/pages/manager/gateways/list.tsx @@ -287,6 +287,7 @@ const MyGatewaysPage: React.FC = () => { px={5} py={2} mb={4} + data-testid={`ns-list-item-${namespace.name}`} > From 82def6cff4ed6343639d5f6fe92bbbfa4e719a26 Mon Sep 17 00:00:00 2001 From: Russell Vinegar Date: Fri, 9 Aug 2024 15:41:42 -0700 Subject: [PATCH 04/21] check Gateways List filtering --- e2e/cypress/pageObjects/namespace.ts | 1 + .../14-org-assignment/01-client-cred-team-access.ts | 12 ++++++++++++ src/nextapp/pages/manager/gateways/list.tsx | 1 + 3 files changed, 14 insertions(+) diff --git a/e2e/cypress/pageObjects/namespace.ts b/e2e/cypress/pageObjects/namespace.ts index d5f1c7ee8..a706bcda0 100644 --- a/e2e/cypress/pageObjects/namespace.ts +++ b/e2e/cypress/pageObjects/namespace.ts @@ -2,6 +2,7 @@ class NameSpacePage { path: string = '/manager/gateways' listPath: string = 'manager/gateways/list' detailPath: string = '/manager/gateways/detail' + listFilterSelect: string = '[data-testid="ns-filter-select"]' gatewayServiceLink: string = '[data-testid="ns-manage-link-Gateway Services"]' productsLink: string = '[data-testid="ns-manage-link-Gateway Services"]' consumersLink: string = '[data-testid="ns-manage-link-Consumers"]' diff --git a/e2e/cypress/tests/14-org-assignment/01-client-cred-team-access.ts b/e2e/cypress/tests/14-org-assignment/01-client-cred-team-access.ts index 5511ff260..9c6c998f9 100644 --- a/e2e/cypress/tests/14-org-assignment/01-client-cred-team-access.ts +++ b/e2e/cypress/tests/14-org-assignment/01-client-cred-team-access.ts @@ -118,6 +118,10 @@ describe('Add Organization to publish API', () => { it('Verify My Gateways shows publishing "disabled"', () => { cy.visit(ns.listPath) cy.get(`[data-testid="ns-list-item-${namespace}"]`).should('contain.text', 'Publishing disabled') + cy.get(ns.listFilterSelect).select('disabled') + cy.get(`[data-testid="ns-list-item-${namespace}"]`).should('exist') + cy.get(ns.listFilterSelect).select('enabled') + cy.get(`[data-testid="ns-list-item-${namespace}"]`).should('not.exist') }) it('Assign organization to the created namespace', () => { @@ -130,6 +134,10 @@ describe('Add Organization to publish API', () => { it('Verify My Gateways shows publishing "pending"', () => { cy.visit(ns.listPath) cy.get(`[data-testid="ns-list-item-${namespace}"]`).should('contain.text', 'Pending publishing permission') + cy.get(ns.listFilterSelect).select('pending') + cy.get(`[data-testid="ns-list-item-${namespace}"]`).should('exist') + cy.get(ns.listFilterSelect).select('enabled') + cy.get(`[data-testid="ns-list-item-${namespace}"]`).should('not.exist') }) it('Verify Organization Administrator notification banner', () => { @@ -218,6 +226,10 @@ describe('Activate the API to make it visible in API Directory', () => { it('Verify My Gateways shows publishing "enabled"', () => { cy.visit(ns.listPath) cy.get(`[data-testid="ns-list-item-${namespace}"]`).should('contain.text', 'Publishing enabled') + cy.get(ns.listFilterSelect).select('enabled') + cy.get(`[data-testid="ns-list-item-${namespace}"]`).should('exist') + cy.get(ns.listFilterSelect).select('disabled') + cy.get(`[data-testid="ns-list-item-${namespace}"]`).should('not.exist') }) it('update the Dataset in BC Data Catelogue to appear the API in the Directory', () => { diff --git a/src/nextapp/pages/manager/gateways/list.tsx b/src/nextapp/pages/manager/gateways/list.tsx index a09125816..7b039d02f 100644 --- a/src/nextapp/pages/manager/gateways/list.tsx +++ b/src/nextapp/pages/manager/gateways/list.tsx @@ -248,6 +248,7 @@ const MyGatewaysPage: React.FC = () => { mr={4} placeholder="Filter by: All" onChange={handleFilterChange} + data-testid="ns-filter-select" > From 68bbf7a0f57b4715fb2334f56ab4d26e2a764374 Mon Sep 17 00:00:00 2001 From: Russell Vinegar Date: Mon, 12 Aug 2024 08:21:26 -0700 Subject: [PATCH 05/21] update validation error msg --- e2e/cypress/tests/19-api-v3/03-gateways.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e/cypress/tests/19-api-v3/03-gateways.ts b/e2e/cypress/tests/19-api-v3/03-gateways.ts index d31c77a98..14af30d7b 100644 --- a/e2e/cypress/tests/19-api-v3/03-gateways.ts +++ b/e2e/cypress/tests/19-api-v3/03-gateways.ts @@ -190,7 +190,7 @@ describe('Gateways', () => { details: { d0: { message: - 'Display name can not be longer than 30 characters and can only use special characters "-()_ .\'/".', + 'Display name must be between 3 and 30 characters, starting with an alpha-numeric character, and can only use special characters "-()_ .\'/".', }, }, } @@ -212,7 +212,7 @@ describe('Gateways', () => { details: { d0: { message: - 'Display name can not be longer than 30 characters and can only use special characters "-()_ .\'/".', + 'Display name must be between 3 and 30 characters, starting with an alpha-numeric character, and can only use special characters "-()_ .\'/".', }, }, } From 9074b3e3297abcbe8d214861c8f3abe71919ccb7 Mon Sep 17 00:00:00 2001 From: Russell Vinegar Date: Mon, 12 Aug 2024 08:50:21 -0700 Subject: [PATCH 06/21] Get Started tests --- e2e/cypress/pageObjects/namespace.ts | 2 + e2e/cypress/support/auth-commands.ts | 2 +- .../tests/01-api-key/00-get-started.cy.ts | 64 +++++++++++++++++++ .../gateway-get-started.tsx | 2 +- .../pages/manager/gateways/get-started.tsx | 3 +- 5 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 e2e/cypress/tests/01-api-key/00-get-started.cy.ts diff --git a/e2e/cypress/pageObjects/namespace.ts b/e2e/cypress/pageObjects/namespace.ts index a706bcda0..db54c2754 100644 --- a/e2e/cypress/pageObjects/namespace.ts +++ b/e2e/cypress/pageObjects/namespace.ts @@ -2,7 +2,9 @@ class NameSpacePage { path: string = '/manager/gateways' listPath: string = 'manager/gateways/list' detailPath: string = '/manager/gateways/detail' + getStartedPath: string = '/manager/gateways/get-started' listFilterSelect: string = '[data-testid="ns-filter-select"]' + listSearchInput: string = '[data-testid="namespace-search-input"]' gatewayServiceLink: string = '[data-testid="ns-manage-link-Gateway Services"]' productsLink: string = '[data-testid="ns-manage-link-Gateway Services"]' consumersLink: string = '[data-testid="ns-manage-link-Consumers"]' diff --git a/e2e/cypress/support/auth-commands.ts b/e2e/cypress/support/auth-commands.ts index a415adcb1..67b39d1ea 100644 --- a/e2e/cypress/support/auth-commands.ts +++ b/e2e/cypress/support/auth-commands.ts @@ -209,7 +209,7 @@ Cypress.Commands.add('resetCredential', (accessRole: string) => { Cypress.Commands.add( 'getUserSessionTokenValue', - (namespace: string, isNamespaceSelected?: boolean) => { + (namespace: string = 'ns', isNamespaceSelected?: boolean) => { const login = new LoginPage() const home = new HomePage() const na = new NamespaceAccessPage() diff --git a/e2e/cypress/tests/01-api-key/00-get-started.cy.ts b/e2e/cypress/tests/01-api-key/00-get-started.cy.ts new file mode 100644 index 000000000..40b5aa32a --- /dev/null +++ b/e2e/cypress/tests/01-api-key/00-get-started.cy.ts @@ -0,0 +1,64 @@ +import LoginPage from '../../pageObjects/login' +import NameSpacePage from '../../pageObjects/namespace' + +// Elements of this page must be checked when there are no Gateways, so this test comes first of all +describe('Gateway Get Started page', () => { + const login = new LoginPage() + const ns = new NameSpacePage() + let userSession: any + let namespace: string + + before(() => { + cy.visit('/') + cy.deleteAllCookies() + cy.reload(true) + cy.resetState() + }) + + beforeEach(() => { + cy.preserveCookies() + cy.fixture('apiowner').as('apiowner') + cy.fixture('common-testdata').as('common-testdata') + }) + + it('authenticates Janis (api owner) to get the user session token', () => { + cy.getUserSessionTokenValue('', false).then((value) => { + userSession = value + }) + }) + + it('Check for redirect to Get Started page', () => { + cy.visit(ns.path) + cy.url().should('include', '/manager/gateways/get-started') + }) + + it('Check for box that says "No gateways"', () => { + cy.get('[data-testid="no-gateways"]').should('exist') + }) + + it('Create a namespace', () => { + cy.createGateway().then((response) => { + namespace = response.gatewayId + }) + }) + + it('Check for banner that says "You have gateways"', () => { + // unfocus and refocus the page to refetch the data + cy.reload() + cy.get('[data-testid="no-gateways"]').should('not.exist') + cy.get('[data-testid="you-have-gateways-banner"]').should('exist') + }) + + it('Cleanup: delete namespace', () => { + cy.activateGateway(namespace) + cy.visit(ns.detailPath) + ns.deleteNamespace(namespace) + }) + + after(() => { + cy.logout() + cy.clearLocalStorage({ log: true }) + cy.deleteAllCookies() + }) + +}) \ No newline at end of file diff --git a/src/nextapp/components/gateway-get-started/gateway-get-started.tsx b/src/nextapp/components/gateway-get-started/gateway-get-started.tsx index 93661d243..bbad093e0 100644 --- a/src/nextapp/components/gateway-get-started/gateway-get-started.tsx +++ b/src/nextapp/components/gateway-get-started/gateway-get-started.tsx @@ -65,7 +65,7 @@ const GatewayGetStarted: React.FC = ({ <> {!hasNamespaces && ( - + { {isError && Gateways Failed to Load} {isSuccess && data.allNamespaces.length != 0 && ( - + From 0dc1cb01580736fa23b6e68eefaacb69e64371c6 Mon Sep 17 00:00:00 2001 From: Russell Vinegar Date: Mon, 12 Aug 2024 09:27:11 -0700 Subject: [PATCH 07/21] remove log --- src/nextapp/pages/manager/gateways/detail.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/nextapp/pages/manager/gateways/detail.tsx b/src/nextapp/pages/manager/gateways/detail.tsx index c245243b0..1bf000e92 100644 --- a/src/nextapp/pages/manager/gateways/detail.tsx +++ b/src/nextapp/pages/manager/gateways/detail.tsx @@ -159,7 +159,6 @@ const NamespacesPage: React.FC = () => { }; }, [namespace]); const handleDelete = React.useCallback(async () => { - console.log('handle delete from detail'); if (user?.namespace) { toast({ title: `Deleting gateway: ${namespace.data?.currentNamespace?.displayName}`, From b79ea6eb72a8b5ef3fb809621af92e7fc52ec916 Mon Sep 17 00:00:00 2001 From: Russell Vinegar Date: Mon, 12 Aug 2024 10:41:10 -0700 Subject: [PATCH 08/21] add deleteGatewayCli command --- e2e/cypress/support/auth-commands.ts | 10 ++++++++++ e2e/cypress/support/global.d.ts | 2 ++ .../tests/01-api-key/00-get-started.cy.ts | 19 +++++++++++++++---- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/e2e/cypress/support/auth-commands.ts b/e2e/cypress/support/auth-commands.ts index 67b39d1ea..4d040f156 100644 --- a/e2e/cypress/support/auth-commands.ts +++ b/e2e/cypress/support/auth-commands.ts @@ -101,6 +101,16 @@ Cypress.Commands.add('createGateway', (gatewayid?: string, displayname?: string) ) }) +Cypress.Commands.add('deleteGatewayCli', (gatewayid: string, force: boolean = false) => { + cy.executeCliCommand('gwa config set gateway ' + gatewayid).then(() => { + cy.executeCliCommand(`gwa gateway destroy ${force ? '--force' : ''}`).then( + (response) => { + console.log(response) + expect(response.stdout).to.contain('Gateway destroyed: ' + gatewayid) + }) + }) +}) + Cypress.Commands.add('activateGateway', (gatewayId: string, checkNoNamespace: boolean = false) => { const getAllNsQuery = ` query GetNamespaces { diff --git a/e2e/cypress/support/global.d.ts b/e2e/cypress/support/global.d.ts index a96743847..433e29b3f 100644 --- a/e2e/cypress/support/global.d.ts +++ b/e2e/cypress/support/global.d.ts @@ -38,6 +38,8 @@ declare namespace Cypress { displayname?: string, ): Chainable + deleteGatewayCli(gatewayid: string, force: boolean): Chainable + activateGateway( gatewayId: string, checkNoNamespace?: boolean diff --git a/e2e/cypress/tests/01-api-key/00-get-started.cy.ts b/e2e/cypress/tests/01-api-key/00-get-started.cy.ts index 40b5aa32a..db41907e0 100644 --- a/e2e/cypress/tests/01-api-key/00-get-started.cy.ts +++ b/e2e/cypress/tests/01-api-key/00-get-started.cy.ts @@ -1,5 +1,6 @@ import LoginPage from '../../pageObjects/login' import NameSpacePage from '../../pageObjects/namespace' +const cleanedUrl = Cypress.env('BASE_URL').replace(/^http?:\/\//i, ""); // Elements of this page must be checked when there are no Gateways, so this test comes first of all describe('Gateway Get Started page', () => { @@ -24,8 +25,21 @@ describe('Gateway Get Started page', () => { it('authenticates Janis (api owner) to get the user session token', () => { cy.getUserSessionTokenValue('', false).then((value) => { userSession = value + console.log('first user session', userSession) }) }) + + it('Set token with gwa config command', () => { + cy.exec('gwa config set --token ' + userSession, { timeout: 3000, failOnNonZeroExit: false }).then((response) => { + expect(response.stdout).to.contain("Config settings saved") + }); + }) + + it('Set environment with gwa config command', () => { + cy.executeCliCommand('gwa config set --host ' + cleanedUrl + ' --scheme http').then((response) => { + expect(response.stdout).to.contain("Config settings saved") + }); + }) it('Check for redirect to Get Started page', () => { cy.visit(ns.path) @@ -43,16 +57,13 @@ describe('Gateway Get Started page', () => { }) it('Check for banner that says "You have gateways"', () => { - // unfocus and refocus the page to refetch the data cy.reload() cy.get('[data-testid="no-gateways"]').should('not.exist') cy.get('[data-testid="you-have-gateways-banner"]').should('exist') }) it('Cleanup: delete namespace', () => { - cy.activateGateway(namespace) - cy.visit(ns.detailPath) - ns.deleteNamespace(namespace) + cy.deleteGatewayCli(namespace, true) }) after(() => { From d0756d76539b147b9dc11a255647e667603fcac0 Mon Sep 17 00:00:00 2001 From: Russell Vinegar Date: Mon, 12 Aug 2024 11:39:09 -0700 Subject: [PATCH 09/21] My Gateways lists gws --- e2e/cypress/fixtures/common-testdata.json | 20 +++++- e2e/cypress/tests/19-gateways/01-list.ts | 76 +++++++++++++++++++++++ 2 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 e2e/cypress/tests/19-gateways/01-list.ts diff --git a/e2e/cypress/fixtures/common-testdata.json b/e2e/cypress/fixtures/common-testdata.json index 6b188709c..98e24a71f 100644 --- a/e2e/cypress/fixtures/common-testdata.json +++ b/e2e/cypress/fixtures/common-testdata.json @@ -10,7 +10,7 @@ "namespace": "gw-16a3a" }, "orgAssignment": { - "namespace": "gw-f016e" + "namespace": "gw-f6a4d" }, "orgAssignmentMultipleAdmin": { "namespace": "orgassignment1" @@ -84,5 +84,23 @@ }, "serviceAvailability": { "namespace": "service-avail" + }, + "myGateways": { + "namespace1": { + "gatewayId": "gw-apple", + "displayName": "Apple" + }, + "namespace2": { + "gatewayId": "gw-banana", + "displayName": "Banana" + }, + "namespace3": { + "gatewayId": "gw-date", + "displayName": "Cherry" + }, + "namespace4": { + "gatewayId": "gw-cherry", + "displayName": "Cherry" + } } } \ No newline at end of file diff --git a/e2e/cypress/tests/19-gateways/01-list.ts b/e2e/cypress/tests/19-gateways/01-list.ts new file mode 100644 index 000000000..7174a4292 --- /dev/null +++ b/e2e/cypress/tests/19-gateways/01-list.ts @@ -0,0 +1,76 @@ +import LoginPage from '../../pageObjects/login' +import NameSpacePage from '../../pageObjects/namespace' +let gateways: any + +const { v4: uuidv4 } = require('uuid') +const customId = uuidv4().replace(/-/g, '').toLowerCase().substring(0, 3) + +describe('My Gateways list page', () => { + const login = new LoginPage() + const ns = new NameSpacePage() + let userSession: any + + before(() => { + cy.deleteAllCookies() + }) + + beforeEach(() => { + cy.preserveCookies() + cy.fixture('apiowner').as('apiowner') + cy.fixture('common-testdata').as('common-testdata') + }) + + it('authenticates Janis (api owner) to get the user session token', () => { + cy.getUserSessionTokenValue('', false).then((value) => { + userSession = value + }) + }) + + it('Set token with gwa config command', () => { + cy.exec('gwa config set --token ' + userSession, { timeout: 3000, failOnNonZeroExit: false }).then((response) => { + expect(response.stdout).to.contain("Config settings saved") + }); + }) + + it('create a set of namespaces', () => { + cy.get('@common-testdata').then(({ myGateways }: any) => { + gateways = myGateways + Cypress._.forEach(gateways, (gateway) => { + cy.createGateway(gateway.gatewayId + '-' + customId, gateway.displayName); + }); + }); + }); + + it('Verify My Gateways shows the created gateways', () => { + cy.visit(ns.listPath) + Cypress._.forEach(gateways, (gateway) => { + cy.get(`[data-testid="ns-list-item-${gateway.gatewayId + '-' + customId}"]`) + .should('contain.text', gateway.displayName) + }); + }) + + it('Cleanup: delete namespaces', () => { + Cypress._.forEach(gateways, (gateway) => { + cy.deleteGatewayCli(gateway.gatewayId + '-' + customId, false) + }); + }) + + + + + // it('Verify My Gateways shows the created gateways', () => { + // cy.visit(ns.listPath) + // cy.get(`[data-testid="ns-list-item-${namespace}"]`) + // .should('contain.text', namespace1) + // }) + // it('activates new namespace', () => { + // cy.activateGateway(namespace) + // }) + + after(() => { + cy.logout() + cy.clearLocalStorage({ log: true }) + cy.deleteAllCookies() + }) + +}) \ No newline at end of file From 637494460466d0b3965f6c621cd61e3273ecf877 Mon Sep 17 00:00:00 2001 From: Russell Vinegar Date: Mon, 12 Aug 2024 12:00:17 -0700 Subject: [PATCH 10/21] go to details page --- e2e/cypress/tests/19-gateways/01-list.ts | 19 +++++++------------ src/nextapp/pages/manager/gateways/list.tsx | 1 + 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/e2e/cypress/tests/19-gateways/01-list.ts b/e2e/cypress/tests/19-gateways/01-list.ts index 7174a4292..112b8ffe9 100644 --- a/e2e/cypress/tests/19-gateways/01-list.ts +++ b/e2e/cypress/tests/19-gateways/01-list.ts @@ -49,23 +49,18 @@ describe('My Gateways list page', () => { }); }) + it('Check Gateway link goes to details page', () => { + var gateway1Id = gateways["namespace1"].gatewayId + '-' + customId + cy.visit(ns.listPath) + cy.get(`[data-testid="ns-list-activate-link-${gateway1Id}"]`).click() + cy.url().should('include', '/manager/gateways/detail') + }) + it('Cleanup: delete namespaces', () => { Cypress._.forEach(gateways, (gateway) => { cy.deleteGatewayCli(gateway.gatewayId + '-' + customId, false) }); }) - - - - - // it('Verify My Gateways shows the created gateways', () => { - // cy.visit(ns.listPath) - // cy.get(`[data-testid="ns-list-item-${namespace}"]`) - // .should('contain.text', namespace1) - // }) - // it('activates new namespace', () => { - // cy.activateGateway(namespace) - // }) after(() => { cy.logout() diff --git a/src/nextapp/pages/manager/gateways/list.tsx b/src/nextapp/pages/manager/gateways/list.tsx index aa33ab831..70c897510 100644 --- a/src/nextapp/pages/manager/gateways/list.tsx +++ b/src/nextapp/pages/manager/gateways/list.tsx @@ -304,6 +304,7 @@ const MyGatewaysPage: React.FC = () => { color="bc-blue" mr={2} onClick={handleNamespaceChange(namespace)} + data-testid={`ns-list-activate-link-${namespace.name}`} > {namespace.displayName} From caebd53e3996d3138d223fc8f29e2d270aa8fde6 Mon Sep 17 00:00:00 2001 From: Russell Vinegar Date: Mon, 12 Aug 2024 14:43:39 -0700 Subject: [PATCH 11/21] test search, filter, export report --- e2e/cypress/pageObjects/namespace.ts | 1 - e2e/cypress/tests/19-gateways/01-list.ts | 52 ++++++++++++++++++++- src/nextapp/pages/manager/gateways/list.tsx | 4 +- 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/e2e/cypress/pageObjects/namespace.ts b/e2e/cypress/pageObjects/namespace.ts index db54c2754..7835e4612 100644 --- a/e2e/cypress/pageObjects/namespace.ts +++ b/e2e/cypress/pageObjects/namespace.ts @@ -4,7 +4,6 @@ class NameSpacePage { detailPath: string = '/manager/gateways/detail' getStartedPath: string = '/manager/gateways/get-started' listFilterSelect: string = '[data-testid="ns-filter-select"]' - listSearchInput: string = '[data-testid="namespace-search-input"]' gatewayServiceLink: string = '[data-testid="ns-manage-link-Gateway Services"]' productsLink: string = '[data-testid="ns-manage-link-Gateway Services"]' consumersLink: string = '[data-testid="ns-manage-link-Consumers"]' diff --git a/e2e/cypress/tests/19-gateways/01-list.ts b/e2e/cypress/tests/19-gateways/01-list.ts index 112b8ffe9..af171fdac 100644 --- a/e2e/cypress/tests/19-gateways/01-list.ts +++ b/e2e/cypress/tests/19-gateways/01-list.ts @@ -1,3 +1,4 @@ +import { report } from 'process' import LoginPage from '../../pageObjects/login' import NameSpacePage from '../../pageObjects/namespace' let gateways: any @@ -35,6 +36,7 @@ describe('My Gateways list page', () => { it('create a set of namespaces', () => { cy.get('@common-testdata').then(({ myGateways }: any) => { gateways = myGateways + gateways["namespace1"] = gateways["namespace1"] Cypress._.forEach(gateways, (gateway) => { cy.createGateway(gateway.gatewayId + '-' + customId, gateway.displayName); }); @@ -50,12 +52,58 @@ describe('My Gateways list page', () => { }) it('Check Gateway link goes to details page', () => { - var gateway1Id = gateways["namespace1"].gatewayId + '-' + customId cy.visit(ns.listPath) - cy.get(`[data-testid="ns-list-activate-link-${gateway1Id}"]`).click() + cy.get(`[data-testid="ns-list-activate-link-${gateways["namespace1"].gatewayId + '-' + customId}"]`).click() cy.url().should('include', '/manager/gateways/detail') }) + it('Test search - find results', () => { + cy.visit(ns.listPath) + cy.get('[data-testid="ns-search-input"]').type(gateways["namespace1"].displayName) + cy.get(`[data-testid="ns-list-item-${gateways["namespace1"].gatewayId + '-' + customId}"]`).should('exist') + cy.get(`[data-testid="ns-list-item-${gateways["namespace2"].gatewayId + '-' + customId}"]`).should('not.exist') + cy.get('[data-testid="ns-search-input"]').clear() + cy.get(`[data-testid="ns-list-item-${gateways["namespace2"].gatewayId + '-' + customId}"]`).should('exist') + }) + + it('Test search - do not find results', () => { + cy.visit(ns.listPath) + cy.get('[data-testid="ns-search-input"]').type('gibberish') + cy.get(`[data-testid="ns-list-item-${gateways["namespace1"].gatewayId + '-' + customId}"]`).should('not.exist') + cy.get('[data-testid="ns-no-results-text"]').should('exist') + }) + + it('Test filter - find results', () => { + cy.visit(ns.listPath) + cy.get('[data-testid="ns-filter-select"]').select('disabled') + cy.get(`[data-testid="ns-list-item-${gateways["namespace1"].gatewayId + '-' + customId}"]`).should('exist') + }) + + it('Test filter - do not find results', () => { + cy.visit(ns.listPath) + cy.get('[data-testid="ns-filter-select"]').select('pending') + cy.get(`[data-testid="ns-list-item-${gateways["namespace1"].gatewayId + '-' + customId}"]`).should('not.exist') + }) + + it('Test filter and search together', () => { + cy.visit(ns.listPath) + cy.get('[data-testid="ns-filter-select"]').select('disabled') + cy.get('[data-testid="ns-search-input"]').type(gateways["namespace1"].displayName) + cy.get(`[data-testid="ns-list-item-${gateways["namespace1"].gatewayId + '-' + customId}"]`).should('exist') + }) + + it('Export Gateway Report', () => { + cy.visit(ns.listPath) + cy.get('[data-testid="ns-report-btn"]').click() + cy.get('[data-testid="export-report-select-all-check"]').click() + cy.get('[data-testid="export-report-export-btn"]').click() + // check that the report is downloaded + const filePath = 'cypress/downloads/gateway-report.xlsx' + cy.readFile(filePath, 'binary', { timeout: 10000 }).then((fileContent) => { + expect(fileContent.length).to.be.greaterThan(0); + }); + }); + it('Cleanup: delete namespaces', () => { Cypress._.forEach(gateways, (gateway) => { cy.deleteGatewayCli(gateway.gatewayId + '-' + customId, false) diff --git a/src/nextapp/pages/manager/gateways/list.tsx b/src/nextapp/pages/manager/gateways/list.tsx index 70c897510..63b9932f4 100644 --- a/src/nextapp/pages/manager/gateways/list.tsx +++ b/src/nextapp/pages/manager/gateways/list.tsx @@ -259,7 +259,7 @@ const MyGatewaysPage: React.FC = () => { onBlur={(event) => event.currentTarget.focus()} onChange={handleSearchChange} value={search} - data-testid="namespace-search-input" + data-testid="ns-search-input" /> {isSuccess && @@ -348,7 +348,7 @@ const MyGatewaysPage: React.FC = () => { justifyContent="center" py={2} > - + No results found From c43327df935de396de7a9914d9cd54a730b6a9b8 Mon Sep 17 00:00:00 2001 From: Russell Vinegar Date: Mon, 12 Aug 2024 15:25:33 -0700 Subject: [PATCH 12/21] test gateways dropdown --- e2e/cypress/pageObjects/apiDirectory.ts | 1 + e2e/cypress/tests/19-gateways/01-list.ts | 2 - e2e/cypress/tests/19-gateways/02-dropdown.ts | 114 ++++++++++++++++++ .../namespace-menu/namespace-menu.tsx | 8 +- 4 files changed, 120 insertions(+), 5 deletions(-) create mode 100644 e2e/cypress/tests/19-gateways/02-dropdown.ts diff --git a/e2e/cypress/pageObjects/apiDirectory.ts b/e2e/cypress/pageObjects/apiDirectory.ts index d0aaf834f..7d69a1584 100644 --- a/e2e/cypress/pageObjects/apiDirectory.ts +++ b/e2e/cypress/pageObjects/apiDirectory.ts @@ -1,6 +1,7 @@ class ApiDirectoryPage { path: string = '/devportal/api-directory' + yourProductsPath: string = '/devportal/api-directory/your-products' rqstAccessBtn: string = '[data-testid=request-access-button]' appSelect: string = '[data-testid=access-application-select]' additionalNotes: string = '[data-testid=access-rqst-add-notes-text]' diff --git a/e2e/cypress/tests/19-gateways/01-list.ts b/e2e/cypress/tests/19-gateways/01-list.ts index af171fdac..d15682ce3 100644 --- a/e2e/cypress/tests/19-gateways/01-list.ts +++ b/e2e/cypress/tests/19-gateways/01-list.ts @@ -1,5 +1,4 @@ import { report } from 'process' -import LoginPage from '../../pageObjects/login' import NameSpacePage from '../../pageObjects/namespace' let gateways: any @@ -7,7 +6,6 @@ const { v4: uuidv4 } = require('uuid') const customId = uuidv4().replace(/-/g, '').toLowerCase().substring(0, 3) describe('My Gateways list page', () => { - const login = new LoginPage() const ns = new NameSpacePage() let userSession: any diff --git a/e2e/cypress/tests/19-gateways/02-dropdown.ts b/e2e/cypress/tests/19-gateways/02-dropdown.ts new file mode 100644 index 000000000..56040e6ab --- /dev/null +++ b/e2e/cypress/tests/19-gateways/02-dropdown.ts @@ -0,0 +1,114 @@ +import NameSpacePage from '../../pageObjects/namespace' +import ApiDirectoryPage from '../../pageObjects/apiDirectory' +let gateways: any +let gateway1: any + +const { v4: uuidv4 } = require('uuid') +const customId = uuidv4().replace(/-/g, '').toLowerCase().substring(0, 3) + +describe('Gateway selector dropdown', () => { + const ns = new NameSpacePage() + const ad = new ApiDirectoryPage() + let userSession: any + + before(() => { + cy.deleteAllCookies() + cy.clearLocalStorage({ log: true }) + }) + + beforeEach(() => { + cy.preserveCookies() + cy.fixture('apiowner').as('apiowner') + cy.fixture('common-testdata').as('common-testdata') + }) + + it('authenticates Janis (api owner) to get the user session token', () => { + cy.getUserSessionTokenValue('', false).then((value) => { + userSession = value + }) + }) + + it('Set token with gwa config command', () => { + cy.exec('gwa config set --token ' + userSession, { timeout: 3000, failOnNonZeroExit: false }).then((response) => { + expect(response.stdout).to.contain("Config settings saved") + }); + }) + + it('create a set of namespaces', () => { + cy.get('@common-testdata').then(({ myGateways }: any) => { + gateways = myGateways + gateway1 = gateways["namespace1"] + Cypress._.forEach(gateways, (gateway) => { + cy.createGateway(gateway.gatewayId + '-' + customId, gateway.displayName); + }); + }); + }); + + it('Verify dropdown shows the total number of gateways', () => { + cy.visit(ad.yourProductsPath) + cy.get('[data-testid="ns-dropdown-btn"]').should('contain.text', "No Active Gateway") + cy.get('[data-testid="ns-dropdown-btn"]').click() + cy.get('[data-testid="ns-dropdown-total-gateways"]').should('contain.text', `You have 4 gateways in total`) + }) + + it('Check Gateway button activates the Gateway', () => { + cy.visit(ad.yourProductsPath) + cy.get('[data-testid="ns-dropdown-btn"]').click() + cy.get(`[data-testid="ns-dropdown-item-${gateways["namespace1"].gatewayId + '-' + customId}"]`).click() + cy.get('h1').should('contain.text', gateways["namespace1"].displayName) + + cy.visit(ns.detailPath) + cy.url().should('include', '/manager/gateways/detail') + cy.get('[data-testid="ns-detail-gateway-display-name"]').should('contain.text', gateways["namespace1"].displayName) + }) + + it('Recently used gateways are shown in the dropdown', () => { + cy.visit(ns.listPath) + cy.get(`[data-testid="ns-list-activate-link-${gateways["namespace1"].gatewayId + '-' + customId}"]`).click() + cy.get('[data-testid="ns-dropdown-btn"]').click() + cy.get(`[data-testid="ns-dropdown-item-${gateways["namespace2"].gatewayId + '-' + customId}"]`).click() + cy.get('[data-testid="ns-dropdown-btn"]').click() + cy.get('[data-testid="ns-dropdown-heading"]').should('contain.text', "Recently viewed") + cy.get(`[data-testid="ns-dropdown-item-${gateways["namespace1"].gatewayId + '-' + customId}"]`).should('exist') + cy.get(`[data-testid="ns-dropdown-item-${gateways["namespace2"].gatewayId + '-' + customId}"]`).should('not.exist') + cy.get(`[data-testid="ns-dropdown-item-${gateways["namespace3"].gatewayId + '-' + customId}"]`).should('not.exist') + }) + + it('Test search - find results', () => { + cy.visit(ns.listPath) + cy.get(`[data-testid="ns-list-activate-link-${gateways["namespace2"].gatewayId + '-' + customId}"]`).click() + cy.visit(ns.listPath) + cy.get(`[data-testid="ns-list-activate-link-${gateways["namespace3"].gatewayId + '-' + customId}"]`).click() + + cy.get('[data-testid="ns-dropdown-btn"]').click() + cy.get('[data-testid="ns-dropdown-search-input"]').type(gateway1.displayName) + cy.get(`[data-testid="ns-dropdown-item-${gateways["namespace1"].gatewayId + '-' + customId}"]`).should('exist') + cy.get(`[data-testid="ns-dropdown-item-${gateways["namespace2"].gatewayId + '-' + customId}"]`).should('not.exist') + cy.get(`[data-testid="ns-dropdown-item-${gateways["namespace3"].gatewayId + '-' + customId}"]`).should('not.exist') + cy.get('[data-testid="ns-dropdown-search-input"]').clear() + cy.get(`[data-testid="ns-dropdown-item-${gateways["namespace2"].gatewayId + '-' + customId}"]`).should('exist') + }) + + it('Test filter - do not find results', () => { + cy.visit(ns.listPath) + cy.get(`[data-testid="ns-list-activate-link-${gateways["namespace1"].gatewayId + '-' + customId}"]`).click() + + cy.get('[data-testid="ns-dropdown-btn"]').click() + cy.get('[data-testid="ns-dropdown-search-input"]').type('gibberish') + cy.get(`[data-testid="ns-dropdown-item-${gateways["namespace1"].gatewayId + '-' + customId}"]`).should('not.exist') + cy.get('[data-testid="ns-dropdown-no-results-box"]').should('exist') + }) + + it('Cleanup: delete namespaces', () => { + Cypress._.forEach(gateways, (gateway) => { + cy.deleteGatewayCli(gateway.gatewayId + '-' + customId, false) + }); + }) + + after(() => { + cy.logout() + cy.clearLocalStorage({ log: true }) + cy.deleteAllCookies() + }) + +}) \ No newline at end of file diff --git a/src/nextapp/components/namespace-menu/namespace-menu.tsx b/src/nextapp/components/namespace-menu/namespace-menu.tsx index f68273755..718b1c62c 100644 --- a/src/nextapp/components/namespace-menu/namespace-menu.tsx +++ b/src/nextapp/components/namespace-menu/namespace-menu.tsx @@ -152,7 +152,7 @@ const NamespaceMenu: React.FC = ({ onBlur={(event) => event.currentTarget.focus()} onChange={handleSearchChange} value={search} - data-testid="namespace-search-input" + data-testid="ns-dropdown-search-input" /> {isLoading && Loading gateways...} @@ -167,6 +167,7 @@ const NamespaceMenu: React.FC = ({ pb={2} m={0} ml={5} + data-testid="ns-dropdown-heading" // @ts-ignore - need bold font in title title={ search !== '' @@ -186,7 +187,8 @@ const NamespaceMenu: React.FC = ({ } > {(search !== '' && namespaceSearchResults.length === 0) && ( - + = ({ - + {`You have ${data.allNamespaces.length} gateway${ data.allNamespaces.length !== 1 ? 's' : '' } in total`} From 3597828a1c9044349aeb45b0a67c8781d9a13255 Mon Sep 17 00:00:00 2001 From: Russell Vinegar Date: Mon, 12 Aug 2024 15:37:36 -0700 Subject: [PATCH 13/21] test edit display name --- e2e/cypress/tests/19-gateways/01-list.ts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/e2e/cypress/tests/19-gateways/01-list.ts b/e2e/cypress/tests/19-gateways/01-list.ts index d15682ce3..e95963d85 100644 --- a/e2e/cypress/tests/19-gateways/01-list.ts +++ b/e2e/cypress/tests/19-gateways/01-list.ts @@ -53,6 +53,7 @@ describe('My Gateways list page', () => { cy.visit(ns.listPath) cy.get(`[data-testid="ns-list-activate-link-${gateways["namespace1"].gatewayId + '-' + customId}"]`).click() cy.url().should('include', '/manager/gateways/detail') + cy.get('h1').should('contain.text', gateways["namespace1"].displayName) }) it('Test search - find results', () => { @@ -90,6 +91,28 @@ describe('My Gateways list page', () => { cy.get(`[data-testid="ns-list-item-${gateways["namespace1"].gatewayId + '-' + customId}"]`).should('exist') }) + it('Edit Gateway display name - valid', () => { + cy.visit(ns.listPath) + cy.get(`[data-testid="ns-list-activate-link-${gateways["namespace1"].gatewayId + '-' + customId}"]`).click() + cy.get('[data-testid="display-name-edit-btn"]').click() + cy.get('[data-testid="edit-display-name-input"]').type(' Pie') + cy.get('[data-testid="edit-display-name-submit-btn"]').click() + cy.get('h1').should('contain.text', 'Apple Pie') + }) + + it('Edit Gateway display name - too short or too long', () => { + cy.visit(ns.listPath) + cy.get(`[data-testid="ns-list-activate-link-${gateways["namespace1"].gatewayId + '-' + customId}"]`).click() + cy.get('[data-testid="display-name-edit-btn"]').click() + cy.get('[data-testid="edit-display-name-input"]').clear().type('12') + cy.get('[data-testid="edit-display-name-submit-btn"]').should('be.disabled') + cy.get('[data-testid="edit-display-name-input"]').clear().type('Supercalifragilisticexpialidocious') + cy.get('[data-testid="edit-display-name-submit-btn"]').should('be.disabled') + cy.get('[data-testid="edit-display-name-input"]').clear().type('A reasonable name') + cy.get('[data-testid="edit-display-name-submit-btn"]').should('be.enabled') + cy.get('[data-testid="edit-display-name-cancel-btn"]').click() + }) + it('Export Gateway Report', () => { cy.visit(ns.listPath) cy.get('[data-testid="ns-report-btn"]').click() From 53c1cdcbfee625fd16c37790621b658f2bc525b7 Mon Sep 17 00:00:00 2001 From: Russell Vinegar Date: Mon, 12 Aug 2024 15:42:05 -0700 Subject: [PATCH 14/21] renumber new folder --- e2e/cypress.config.ts | 1 + e2e/cypress/tests/{19-gateways => 20-gateways}/01-list.ts | 0 e2e/cypress/tests/{19-gateways => 20-gateways}/02-dropdown.ts | 0 3 files changed, 1 insertion(+) rename e2e/cypress/tests/{19-gateways => 20-gateways}/01-list.ts (100%) rename e2e/cypress/tests/{19-gateways => 20-gateways}/02-dropdown.ts (100%) diff --git a/e2e/cypress.config.ts b/e2e/cypress.config.ts index 56bfe6029..43b2102f1 100644 --- a/e2e/cypress.config.ts +++ b/e2e/cypress.config.ts @@ -39,6 +39,7 @@ export default defineConfig({ './cypress/tests/17-*/*.ts', './cypress/tests/18-*/*.ts', './cypress/tests/19-*/*.ts', + './cypress/tests/20-*/*.ts', ] return config }, diff --git a/e2e/cypress/tests/19-gateways/01-list.ts b/e2e/cypress/tests/20-gateways/01-list.ts similarity index 100% rename from e2e/cypress/tests/19-gateways/01-list.ts rename to e2e/cypress/tests/20-gateways/01-list.ts diff --git a/e2e/cypress/tests/19-gateways/02-dropdown.ts b/e2e/cypress/tests/20-gateways/02-dropdown.ts similarity index 100% rename from e2e/cypress/tests/19-gateways/02-dropdown.ts rename to e2e/cypress/tests/20-gateways/02-dropdown.ts From 09a5808207400f0e69acaf0b37c2b7b1da22e6a1 Mon Sep 17 00:00:00 2001 From: Russell Vinegar Date: Tue, 13 Aug 2024 08:10:33 -0700 Subject: [PATCH 15/21] handle pre-existing gws, add dependencies --- e2e/cypress/tests/20-gateways/02-dropdown.ts | 22 ++++++++++++++++--- e2e/test-data-dependencies.md | 6 ++++- .../namespace-menu/namespace-menu.tsx | 19 ++++++++++------ 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/e2e/cypress/tests/20-gateways/02-dropdown.ts b/e2e/cypress/tests/20-gateways/02-dropdown.ts index 56040e6ab..8841c581c 100644 --- a/e2e/cypress/tests/20-gateways/02-dropdown.ts +++ b/e2e/cypress/tests/20-gateways/02-dropdown.ts @@ -2,6 +2,7 @@ import NameSpacePage from '../../pageObjects/namespace' import ApiDirectoryPage from '../../pageObjects/apiDirectory' let gateways: any let gateway1: any +let totalGateways: number const { v4: uuidv4 } = require('uuid') const customId = uuidv4().replace(/-/g, '').toLowerCase().substring(0, 3) @@ -34,6 +35,21 @@ describe('Gateway selector dropdown', () => { }); }) + it('Get current total number of gateways', () => { + // Create a new gateway to ensure there is at least one gateway + cy.createGateway(); + + cy.visit(ad.yourProductsPath); + cy.get('[data-testid="ns-dropdown-btn"]').click(); + cy.get('[data-testid="ns-dropdown-total-gateways"]').should('be.visible').then(($el) => { + const totalText = $el.text(); + totalGateways = parseInt( + totalText.replace(/You have /, '').replace(/ Gateways in total/, '') + ); + cy.log('Existing gateways: ' + totalGateways); + }); + }) + it('create a set of namespaces', () => { cy.get('@common-testdata').then(({ myGateways }: any) => { gateways = myGateways @@ -44,11 +60,11 @@ describe('Gateway selector dropdown', () => { }); }); - it('Verify dropdown shows the total number of gateways', () => { + it('Verify dropdown shows the new total number of gateways', () => { cy.visit(ad.yourProductsPath) cy.get('[data-testid="ns-dropdown-btn"]').should('contain.text', "No Active Gateway") cy.get('[data-testid="ns-dropdown-btn"]').click() - cy.get('[data-testid="ns-dropdown-total-gateways"]').should('contain.text', `You have 4 gateways in total`) + cy.get('[data-testid="ns-dropdown-total-gateways"]').should('contain.text', `You have ${totalGateways + 4} Gateways in total`) }) it('Check Gateway button activates the Gateway', () => { @@ -106,7 +122,7 @@ describe('Gateway selector dropdown', () => { }) after(() => { - cy.logout() + // cy.logout() cy.clearLocalStorage({ log: true }) cy.deleteAllCookies() }) diff --git a/e2e/test-data-dependencies.md b/e2e/test-data-dependencies.md index b813512a5..06314847e 100644 --- a/e2e/test-data-dependencies.md +++ b/e2e/test-data-dependencies.md @@ -1,6 +1,7 @@ | Test | Dependencies | | ----------------------------------------------------------- | -------------------------------------------------------------- | | 01-api-key | | +| │   00-get-started.cy.ts | Must run without existing namespaces| | │   01-create-api.cy.ts | NA | | │   02-team-access.cy.ts | 1.1 | | │   03-request-access-inactive-env.cy.ts | 1.1 to 1.2 | @@ -116,4 +117,7 @@ | |   04-products.cy.ts | ? | | |   05-issuers.cy.ts | ? | | |   06-identifiers.cy.ts | ? | -| |   07-endpoints.cy.ts | ? | \ No newline at end of file +| |   07-endpoints.cy.ts | ? | +| 20-gateways | | +| |   01-list.cy.ts | NA | +| |   02-create.cy.ts | NA | \ No newline at end of file diff --git a/src/nextapp/components/namespace-menu/namespace-menu.tsx b/src/nextapp/components/namespace-menu/namespace-menu.tsx index 718b1c62c..5c8253560 100644 --- a/src/nextapp/components/namespace-menu/namespace-menu.tsx +++ b/src/nextapp/components/namespace-menu/namespace-menu.tsx @@ -78,7 +78,7 @@ const NamespaceMenu: React.FC = ({ const handleNamespaceChange = React.useCallback( (namespace: Namespace) => async () => { toast({ - title: `Switching to gateway: ${namespace.displayName}`, + title: `Switching to Gateway: ${namespace.displayName}`, status: 'info', isClosable: true, }); @@ -89,14 +89,14 @@ const NamespaceMenu: React.FC = ({ toast.closeAll(); client.invalidateQueries(); toast({ - title: `Switched to gateway: ${namespace.displayName}`, + title: `Switched to Gateway: ${namespace.displayName}`, status: 'success', isClosable: true, }); } catch (err) { toast.closeAll(); toast({ - title: 'Unable to switch gateways', + title: 'Unable to switch Gateways', status: 'error', isClosable: true, }); @@ -148,14 +148,14 @@ const NamespaceMenu: React.FC = ({ event.currentTarget.focus()} onChange={handleSearchChange} value={search} data-testid="ns-dropdown-search-input" /> - {isLoading && Loading gateways...} + {isLoading && Loading Gateways...} {isError && ( Gateways Failed to Load )} @@ -221,7 +221,7 @@ const NamespaceMenu: React.FC = ({ - {`You have ${data.allNamespaces.length} gateway${ + {`You have ${data.allNamespaces.length} Gateway${ data.allNamespaces.length !== 1 ? 's' : '' } in total`} @@ -239,12 +239,17 @@ const NamespaceMenu: React.FC = ({ > Go to the{' '} - full gateways list + full Gateways list )} + {isSuccess && data.allNamespaces.length === 0 && ( + + No Gateways found + + )} From fb748ca8968cc780be6628f84890a6a9345c8c2f Mon Sep 17 00:00:00 2001 From: Russell Vinegar Date: Tue, 13 Aug 2024 15:27:23 -0700 Subject: [PATCH 16/21] specify output filename (default update pending in cli) --- e2e/cypress/tests/16-gwa-cli/02-cli-generate-config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/cypress/tests/16-gwa-cli/02-cli-generate-config.ts b/e2e/cypress/tests/16-gwa-cli/02-cli-generate-config.ts index 8f0e0a1aa..e090a8ad6 100644 --- a/e2e/cypress/tests/16-gwa-cli/02-cli-generate-config.ts +++ b/e2e/cypress/tests/16-gwa-cli/02-cli-generate-config.ts @@ -45,7 +45,7 @@ describe('Verify CLI commands for generate/apply config', () => { }) it('Check gwa command to generate config for client credential template', () => { - cy.executeCliCommand('gwa generate-config --template client-credentials-shared-idp --service my-service --upstream https://httpbin.org --org ministry-of-health --org-unit planning-and-innovation-division').then((response) => { + cy.executeCliCommand('gwa generate-config --template client-credentials-shared-idp --service my-service --upstream https://httpbin.org --org ministry-of-health --org-unit planning-and-innovation-division --out gw-config.yaml').then((response) => { expect(response.stdout).to.contain("File gw-config.yaml created") }); }) From df41035a4009b79d1531fc9f6abefdd1ff0843d7 Mon Sep 17 00:00:00 2001 From: Russell Vinegar Date: Wed, 14 Aug 2024 10:19:38 -0700 Subject: [PATCH 17/21] fix extract FAILED_TESTS --- .github/workflows/aps-cypress-e2e.yaml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/aps-cypress-e2e.yaml b/.github/workflows/aps-cypress-e2e.yaml index e918f17a6..8a8046f89 100644 --- a/.github/workflows/aps-cypress-e2e.yaml +++ b/.github/workflows/aps-cypress-e2e.yaml @@ -106,7 +106,15 @@ jobs: run: | FAILURE_COUNT=$(cat ${{ github.workspace }}/e2e/results/bcgov-aps-e2e-report.json | jq '.stats.failures') if [[ "$FAILURE_COUNT" -gt 0 ]]; then - FAILED_TESTS=$(jq -r '.results[] | {file: .file, suites: .suites[]} | .suites as $suite | {file: .file, failed_tests: ($suite.tests[] | select(.fail == true) | {title})} | select(.failed_tests != null) | "- " + (.file | split("/") | .[2:] | join("/")) + " - " + .failed_tests.title' ${{ github.workspace }}/e2e/results/bcgov-aps-e2e-report.json) + FAILED_TESTS=$(jq -r ' + .results[] | + (.file | split("/") | .[2:] | join("/")) as $file | + .. | + .tests? // empty | + .[] | + select(.fail == true) | + "- " + $file + " - " + .title + ' ${{ github.workspace }}/e2e/results/bcgov-aps-e2e-report.json) STATS=$(cat ${{ github.workspace }}/e2e/results/bcgov-aps-e2e-report.json | jq -r '.stats | to_entries | map("\(.key)\t\(.value)") | .[]' | column -t) echo -e "Stats: $STATS\n\nFailed Tests:\n$FAILED_TESTS\n\nRun Link: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" > msg export MSG=$(cat msg) From 89a9efe4803b2fd6a59bf26e1078838a2cde217d Mon Sep 17 00:00:00 2001 From: Russell Vinegar Date: Wed, 14 Aug 2024 10:35:49 -0700 Subject: [PATCH 18/21] fix failing shared-idp test --- e2e/cypress/fixtures/api.json | 2 +- .../tests/09-update-product-env/06-shared-idp.cy.ts | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/e2e/cypress/fixtures/api.json b/e2e/cypress/fixtures/api.json index 83779b63f..9ef3f2343 100644 --- a/e2e/cypress/fixtures/api.json +++ b/e2e/cypress/fixtures/api.json @@ -185,7 +185,7 @@ "owner": "janis@idir" }, "shared_IDP_update_body": { - "name": "Sample Shared IdP", + "name": "Sample Shared IdP updated", "description": "A Shared IdP for Teams to use", "flow": "client-credentials", "clientAuthenticator": "client-secret", diff --git a/e2e/cypress/tests/09-update-product-env/06-shared-idp.cy.ts b/e2e/cypress/tests/09-update-product-env/06-shared-idp.cy.ts index e6e6adefb..42ce5c3dc 100644 --- a/e2e/cypress/tests/09-update-product-env/06-shared-idp.cy.ts +++ b/e2e/cypress/tests/09-update-product-env/06-shared-idp.cy.ts @@ -117,14 +117,6 @@ describe('Update IDP issuer for shared IDP profile', () => { }) }) - it('Prepare the Request Specification for the API', () => { - cy.get('@api').then(({ authorizationProfiles }: any) => { - cy.setHeaders(authorizationProfiles.headers) - cy.setAuthorizationToken(userSession) - cy.setRequestBody(authorizationProfiles.shared_IDP_body) - }) - }) - it('Prepare the Request Specification for the API', () => { cy.get('@api').then(({ authorizationProfiles }: any) => { cy.setHeaders(authorizationProfiles.headers) From ed416ad5e502c541d566d1530f5f86e3d3d591ac Mon Sep 17 00:00:00 2001 From: Russell Vinegar Date: Wed, 14 Aug 2024 12:54:01 -0700 Subject: [PATCH 19/21] add retry for flaky org/activity --- .../tests/19-api-v3/02-organization.ts | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/e2e/cypress/tests/19-api-v3/02-organization.ts b/e2e/cypress/tests/19-api-v3/02-organization.ts index 67438850b..4a233992f 100644 --- a/e2e/cypress/tests/19-api-v3/02-organization.ts +++ b/e2e/cypress/tests/19-api-v3/02-organization.ts @@ -136,13 +136,20 @@ describe('Organization', () => { }) it('GET /organizations/{org}/activity', () => { - cy.callAPI('ds/api/v3/organizations/ministry-of-health/activity', 'GET').then( - ({ apiRes: { status, body } }: any) => { - expect(status).to.be.equal(200) - // expect(JSON.stringify(body.filter(a => a.params.ns == ))).to.be.equal(JSON.stringify(match)) - } - ) - }) + // Retry logic if the 422 error occurs + cy.callAPI('ds/api/v3/organizations/ministry-of-health/activity', 'GET') + .then(({ apiRes: { status, body } }: any) => { + if (status === 422) { + cy.wait(2000); + cy.callAPI('ds/api/v3/organizations/ministry-of-health/activity', 'GET') + .then(({ apiRes: { status, body } }: any) => { + expect(status).to.be.equal(200); + }); + } else { + expect(status).to.be.equal(200); + } + }); + }); it('PUT /organizations/{org}/{orgUnit}/gateways/{gatewayId}', () => { cy.setRequestBody({}) From 921d93617d95d06bffaa67df6a348ac81d393cff Mon Sep 17 00:00:00 2001 From: Russell Vinegar Date: Wed, 14 Aug 2024 12:58:28 -0700 Subject: [PATCH 20/21] correct index for issuer --- e2e/cypress/tests/19-api-v3/05-issuers.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/e2e/cypress/tests/19-api-v3/05-issuers.ts b/e2e/cypress/tests/19-api-v3/05-issuers.ts index 2e903b6fe..9e50c781e 100644 --- a/e2e/cypress/tests/19-api-v3/05-issuers.ts +++ b/e2e/cypress/tests/19-api-v3/05-issuers.ts @@ -37,11 +37,11 @@ describe('Authorization Profiles', () => { const issuer = body[0] expect(issuer.name).to.be.equal(`my-auth-profile-for-${gateway.gatewayId}`) - expect(issuer.environmentDetails[0].environment).to.be.equal('test') - expect(issuer.environmentDetails[0].issuerUrl).to.be.equal( + expect(issuer.environmentDetails[1].environment).to.be.equal('test') + expect(issuer.environmentDetails[1].issuerUrl).to.be.equal( Cypress.env('OIDC_ISSUER') ) - expect(issuer.environmentDetails[0].clientId).to.be.equal( + expect(issuer.environmentDetails[1].clientId).to.be.equal( `ap-my-auth-profile-for-${gateway.gatewayId}-test` ) } From ff77d4a95521b7b971007e12fc0d917ed44e3c53 Mon Sep 17 00:00:00 2001 From: Russell Vinegar Date: Wed, 14 Aug 2024 13:19:51 -0700 Subject: [PATCH 21/21] resolve fails on delete-resources tests --- .../tests/01-api-key/00-get-started.cy.ts | 1 - .../05-delete-resources.cy.ts | 44 ++++++++++++++++--- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/e2e/cypress/tests/01-api-key/00-get-started.cy.ts b/e2e/cypress/tests/01-api-key/00-get-started.cy.ts index db41907e0..60d30074e 100644 --- a/e2e/cypress/tests/01-api-key/00-get-started.cy.ts +++ b/e2e/cypress/tests/01-api-key/00-get-started.cy.ts @@ -25,7 +25,6 @@ describe('Gateway Get Started page', () => { it('authenticates Janis (api owner) to get the user session token', () => { cy.getUserSessionTokenValue('', false).then((value) => { userSession = value - console.log('first user session', userSession) }) }) diff --git a/e2e/cypress/tests/10-clear-resources/05-delete-resources.cy.ts b/e2e/cypress/tests/10-clear-resources/05-delete-resources.cy.ts index 23fb01161..855994ad4 100644 --- a/e2e/cypress/tests/10-clear-resources/05-delete-resources.cy.ts +++ b/e2e/cypress/tests/10-clear-resources/05-delete-resources.cy.ts @@ -4,6 +4,8 @@ import NameSpacePage from '../../pageObjects/namespace' import Products from '../../pageObjects/products' import ServiceAccountsPage from '../../pageObjects/serviceAccounts' +const cleanedUrl = Cypress.env('BASE_URL').replace(/^http?:\/\//i, ""); + describe('Delete created resources', () => { const login = new LoginPage() const home = new HomePage() @@ -11,6 +13,7 @@ describe('Delete created resources', () => { const pd = new Products() const ns = new NameSpacePage let flag: boolean + let userSession: any before(() => { cy.visit('/') @@ -30,6 +33,9 @@ describe('Delete created resources', () => { cy.get('@common-testdata').then(({ deleteResources }: any) => { cy.login(user.credentials.username, user.credentials.password) cy.activateGateway(deleteResources.namespace); + cy.getUserSessionTokenValue(deleteResources.namespace, false).then((value) => { + userSession = value + }) }) }) }) @@ -57,11 +63,21 @@ describe('Delete created resources', () => { sa.deleteAllServiceAccounts() }) - it('Delete Namespace', () => { + it('Set token with gwa config command', () => { + cy.exec('gwa config set --token ' + userSession, { timeout: 3000, failOnNonZeroExit: false }).then((response) => { + expect(response.stdout).to.contain("Config settings saved") + }); + }) + + it('Set environment with gwa config command', () => { + cy.executeCliCommand('gwa config set --host ' + cleanedUrl + ' --scheme http').then((response) => { + expect(response.stdout).to.contain("Config settings saved") + }); + }) + + it('Delete Namespace (CLI)', () => { cy.get('@common-testdata').then(({ deleteResources }: any) => { - cy.visit(ns.detailPath) - ns.deleteNamespace(deleteResources.namespace) - cy.wait(10000) + cy.deleteGatewayCli(deleteResources.namespace, true) }); }); @@ -71,14 +87,30 @@ describe('Delete created resources', () => { cy.wrap(null).then(() => { return cy.getGateways(); }).then((result) => { - console.log(result); const namespaceNames = result.map((ns: { name: any }) => ns.name); - console.log(namespaceNames); expect(namespaceNames).to.not.include(deleteResources.namespace); }); }); }); + it('Verify delete namespace works from the UI', () => { + cy.createGateway().then((response) => { + const namespace = response.gatewayId + cy.log('New namespace created: ' + namespace) + cy.activateGateway(namespace); + cy.visit(ns.detailPath) + ns.deleteNamespace(namespace) + + cy.visit('/') + cy.wrap(null).then(() => { + return cy.getGateways(); + }).then((result) => { + const namespaceNames = result.map((ns: { name: any }) => ns.name); + expect(namespaceNames).to.not.include(namespace); + }); + }); + }); + after(() => { cy.logout()