Skip to content

Commit

Permalink
test(dashboard): setup cypress dashboard (#3519)
Browse files Browse the repository at this point in the history
* chore: setting up testid

cherry-pick

rebase

* test: added callback test

rebase

* chore: added api-key test-id and setup initial startup

rebase

* chore: added dashboard test in tilt

rebase

* chore: added testconfig

* chore: added consent as deps

* test: fix test? and lint command fix

* test: fix test?

* test: using email test for consent integration

* test: added test wait

* fix: updated test deps

* test: changes in test

rebase

* test: added redis flush in test and misc changes in test

* chore: updated nextjs

rebase

rebase

* chore: change next ver to 14.0.1

rebase

* test: test changes

* test: added test retries

* chore: updated deps

rebase

* test: test refactor

* test: test refactor

* chore: update deps

* test: changes in test for new consent options

* chore: added svix env in tilt

rebase

* chore: misc changes in test

rebase

* chore: add svix secret

rebase

* test: split commands in test

* chore: rebase changes

* chore: fix tilt syntax error

---------

Co-authored-by: Siddharth <siddharth@debian.siddharth>
  • Loading branch information
siddhart1o1 and Siddharth authored Nov 21, 2023
1 parent 32dd95e commit 5d900a1
Show file tree
Hide file tree
Showing 18 changed files with 376 additions and 11 deletions.
4 changes: 4 additions & 0 deletions apps/consent/cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,8 @@ export default defineConfig({
},
screenshotOnRunFailure: false,
video: false,
retries: {
openMode: 1,
runMode: 2,
},
})
1 change: 1 addition & 0 deletions apps/consent/cypress/e2e/email-sign-in/login-email.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ describe("Account ID Test", () => {
let login_challenge: string | null

before(() => {
cy.flushRedis()
cy.visit(testData.AUTHORIZATION_URL)
cy.url().then((currentUrl) => {
const urlObj = new URL(currentUrl)
Expand Down
1 change: 1 addition & 0 deletions apps/consent/cypress/e2e/phone-sign-in/login-phone.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ describe("Account ID Test", () => {
let login_challenge: string | null

before(() => {
cy.flushRedis()
cy.visit(testData.AUTHORIZATION_URL)
cy.url().then((currentUrl) => {
const urlObj = new URL(currentUrl)
Expand Down
12 changes: 12 additions & 0 deletions apps/consent/cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ declare namespace Cypress {
interface Chainable<Subject> {
getOTP(email: string): Chainable<string>
requestEmailCode(email: string): Chainable<string>
flushRedis(): Chainable<void>
}
}

Expand Down Expand Up @@ -71,3 +72,14 @@ Cypress.Commands.add("requestEmailCode", (email) => {
return response.body.result
})
})

Cypress.Commands.add("flushRedis", () => {
const command = `docker exec galoy-dev-redis-1 redis-cli FLUSHALL`
cy.exec(command).then((result) => {
if (result.code === 0) {
cy.log("Redis FLUSHALL executed successfully")
} else {
throw new Error("Failed to execute FLUSHALL on Redis")
}
})
})
13 changes: 12 additions & 1 deletion apps/dashboard/BUCK
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
load(
"@toolchains//workspace-pnpm:macros.bzl",
"dev_pnpm_task_binary",
"dev_pnpm_task_test",
"build_node_modules",
"next_build",
"next_build_bin",
Expand All @@ -15,7 +16,17 @@ dev_pnpm_task_binary(

dev_pnpm_task_binary(
name = "lint-fix",
command = "dev",
command = "lint:fix",
)

dev_pnpm_task_binary(
name = "cypress-open",
command = "cypress:open",
)

dev_pnpm_task_test(
name = "test-integration",
command = "cypress:run",
)

export_file(
Expand Down
26 changes: 26 additions & 0 deletions apps/dashboard/cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { defineConfig } from "cypress"
import dotenv from "dotenv"

dotenv.config({ path: "../../dev/.envs/next-auth-session.env" })

export default defineConfig({
e2e: {
baseUrl: "http://localhost:3001",
},
defaultCommandTimeout: 60000,
env: {
NEXT_AUTH_SESSION_TOKEN: process.env.NEXT_AUTH_SESSION_TOKEN,
},
component: {
devServer: {
framework: "next",
bundler: "webpack",
},
},
screenshotOnRunFailure: false,
video: false,
retries: {
openMode: 1,
runMode: 2,
},
})
47 changes: 47 additions & 0 deletions apps/dashboard/cypress/e2e/api-keys/api-keys.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { testData } from "../../support/test-data"

describe("Callback Test", () => {
beforeEach(() => {
cy.viewport(1920, 1080)
cy.setCookie("next-auth.session-token", testData.NEXT_AUTH_SESSION_TOKEN, {
secure: true,
})
cy.visit("/")
cy.get("[data-testid=sidebar-api-keys-link]").should("exist")
cy.get("[data-testid=sidebar-api-keys-link]").should("be.visible")
cy.get("[data-testid=sidebar-api-keys-link]").should("not.be.disabled")
cy.get("[data-testid=sidebar-api-keys-link]").click()
})

it("Api Key creation Test", () => {
cy.get('[data-testid="create-api-add-btn"]').should("exist")
cy.get('[data-testid="create-api-add-btn"]').should("be.visible")
cy.get('[data-testid="create-api-add-btn"]').should("not.be.disabled")
cy.get('[data-testid="create-api-add-btn"]').click()

cy.get('[data-testid="create-api-name-input"]').should("exist")
cy.get('[data-testid="create-api-name-input"]').should("be.visible")
cy.get('[data-testid="create-api-name-input"]').should("not.be.disabled")
cy.get('[data-testid="create-api-name-input"]').type("New API Key")

cy.get('[data-testid="create-api-expire-select"]').should("exist")
cy.get('[data-testid="create-api-expire-select"]').should("be.visible")
cy.get('[data-testid="create-api-expire-select"]').should("not.be.disabled")
cy.get('[data-testid="create-api-expire-select"]').click()

cy.get('[data-testid="create-api-expire-30-days-select"]').should("exist")
cy.get('[data-testid="create-api-expire-30-days-select"]').should("be.visible")
cy.get('[data-testid="create-api-expire-30-days-select"]').should("not.be.disabled")
cy.get('[data-testid="create-api-expire-30-days-select"]').click()

cy.get('[data-testid="create-api-create-btn"]').should("exist")
cy.get('[data-testid="create-api-create-btn"]').should("be.visible")
cy.get('[data-testid="create-api-create-btn"]').should("not.be.disabled")
cy.get('[data-testid="create-api-create-btn"]').click()

cy.get('[data-testid="create-api-close-btn"]').should("exist")
cy.get('[data-testid="create-api-close-btn"]').should("be.visible")
cy.get('[data-testid="create-api-close-btn"]').should("not.be.disabled")
cy.get('[data-testid="create-api-close-btn"]').click()
})
})
73 changes: 73 additions & 0 deletions apps/dashboard/cypress/e2e/callback/callback.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { testData } from "../../support/test-data"

describe("Callback Test", () => {
let callbackId: string | undefined

beforeEach(() => {
cy.viewport(1920, 1080)
cy.setCookie("next-auth.session-token", testData.NEXT_AUTH_SESSION_TOKEN, {
secure: true,
})
cy.visit("/")

cy.get("[data-testid=sidebar-callback-link]").should("exist")
cy.get("[data-testid=sidebar-callback-link]").should("be.visible")
cy.get("[data-testid=sidebar-callback-link]").should("not.be.disabled")
cy.get("[data-testid=sidebar-callback-link]").click()
})

it("Callback Addition Test", () => {
cy.get("[data-testid=add-callback-btn]").should("exist")
cy.get("[data-testid=add-callback-btn]").should("be.visible")
cy.get("[data-testid=add-callback-btn]").should("not.be.disabled")
cy.get("[data-testid=add-callback-btn]").click()

cy.get("[data-testid=add-callback-input]").should("exist")
cy.get("[data-testid=add-callback-input]").should("be.visible")
cy.get("[data-testid=add-callback-input]").should("not.be.disabled")
cy.get("[data-testid=add-callback-input]").type(testData.CALLBACK_URL)

cy.get("[data-testid=add-callback-create-btn]").should("exist")
cy.get("[data-testid=add-callback-create-btn]").should("be.visible")
cy.get("[data-testid=add-callback-create-btn]").should("not.be.disabled")
cy.get("[data-testid=add-callback-create-btn]").click()

cy.contains("td", testData.CALLBACK_URL)
.should("exist")
.parent("tr")
.invoke("attr", "data-testid")
.then((id) => {
callbackId = id
cy.log("Callback ID:", id)
})
})

it("Callback Deletion Test", () => {
expect(callbackId).to.exist
cy.get(`[data-testid="delete-callback-btn-${callbackId}"]`)
.filter(":visible")
.should("exist")
cy.get(`[data-testid="delete-callback-btn-${callbackId}"]`)
.filter(":visible")
.should("be.visible")
cy.get(`[data-testid="delete-callback-btn-${callbackId}"]`)
.filter(":visible")
.should("not.be.disabled")
cy.get(`[data-testid="delete-callback-btn-${callbackId}"]`).filter(":visible").click()

cy.get(`[data-testid="delete-callback-confirm-btn-${callbackId}"]`)
.filter(":visible")
.should("exist")
cy.get(`[data-testid="delete-callback-confirm-btn-${callbackId}"]`)
.filter(":visible")
.should("be.visible")
cy.get(`[data-testid="delete-callback-confirm-btn-${callbackId}"]`)
.filter(":visible")
.should("not.be.disabled")
cy.get(`[data-testid="delete-callback-confirm-btn-${callbackId}"]`)
.filter(":visible")
.click()

cy.get(`[data-testid="${callbackId}"]`).should("not.exist")
})
})
68 changes: 68 additions & 0 deletions apps/dashboard/cypress/e2e/consent-integration.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
describe("Consent integration Test", () => {
const signInData = {
EMAIL: "test@galoy.io",
}

before(() => {
cy.flushRedis()
cy.visit("/api/auth/signin")
})

it("Consent integration", () => {
cy.contains("button", "Sign in with Blink").should("exist")
cy.contains("button", "Sign in with Blink").should("be.visible")
cy.contains("button", "Sign in with Blink").should("not.be.disabled")
cy.contains("button", "Sign in with Blink").click()

const email = signInData.EMAIL
cy.get("[data-testid=email_id_input]").should("exist")
cy.get("[data-testid=email_id_input]").should("be.visible")
cy.get("[data-testid=email_id_input]").should("not.be.disabled")
cy.get("[data-testid=email_id_input]").type(email)

cy.get("[data-testid=email_login_next_btn]").should("exist")
cy.get("[data-testid=email_login_next_btn]").should("be.visible")
cy.get("[data-testid=email_login_next_btn]").should("not.be.disabled")
cy.get("[data-testid=email_login_next_btn]").click()

cy.getOTP(email).then((otp) => {
const code = otp
cy.get("[data-testid=verification_code_input]").should("exist")
cy.get("[data-testid=verification_code_input]").should("be.visible")
cy.get("[data-testid=verification_code_input]").should("not.be.disabled")
cy.get("[data-testid=verification_code_input]").type(code)

cy.contains("label", "read").should("exist")
cy.contains("label", "read").should("be.visible")
cy.contains("label", "read").should("not.be.disabled")
cy.contains("label", "read").should("not.be.disabled")
cy.contains("label", "read").click()

cy.contains("label", "write").should("exist")
cy.contains("label", "write").should("be.visible")
cy.contains("label", "write").should("not.be.disabled")
cy.contains("label", "write").click()

cy.get("[data-testid=submit_consent_btn]").should("exist")
cy.get("[data-testid=submit_consent_btn]").should("be.visible")
cy.get("[data-testid=submit_consent_btn]").should("not.be.disabled")
cy.get("[data-testid=submit_consent_btn]").click()

cy.url().should("eq", Cypress.config().baseUrl + "/")
cy.getCookie("next-auth.session-token").then((cookie) => {
if (cookie && cookie.value) {
cy.writeFile(
"../../dev/.envs/next-auth-session.env",
`NEXT_AUTH_SESSION_TOKEN=${cookie.value}\n`,
{
flag: "w",
},
)
cy.log("Session token saved to next-auth-session.test")
} else {
cy.log("Session token not found")
}
})
})
})
})
2 changes: 2 additions & 0 deletions apps/dashboard/cypress/e2e/e2e.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import "./api-keys/api-keys.cy"
import "./callback/callback.cy"
71 changes: 71 additions & 0 deletions apps/dashboard/cypress/support/commands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/// <reference types="cypress" />
// ***********************************************
// This example commands.ts shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
//
// declare global {
// namespace Cypress {
// interface Chainable {
// login(email: string, password: string): Chainable<void>
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
// }
// }
// }

// eslint-disable-next-line @typescript-eslint/no-namespace
declare namespace Cypress {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface Chainable<Subject> {
getOTP(email: string): Chainable<string>
requestEmailCode(email: string): Chainable<string>
flushRedis(): Chainable<void>
}
}

Cypress.Commands.add("getOTP", (email) => {
const query = `docker exec -i galoy-dev-kratos-pg-1 psql -U dbuser -d default -t -c "SELECT body FROM courier_messages WHERE recipient='${email}' ORDER BY created_at DESC LIMIT 1;"`
cy.exec(query).then((result) => {
const rawMessage = result.stdout
const otpMatch = rawMessage.match(/(\d{6})/)
if (otpMatch && otpMatch[1]) {
return otpMatch[1]
} else {
throw new Error("OTP not found in the message")
}
})
})

Cypress.Commands.add("flushRedis", () => {
const command = `docker exec galoy-dev-redis-1 redis-cli FLUSHALL`
cy.exec(command).then((result) => {
if (result.code === 0) {
cy.log("Redis FLUSHALL executed successfully")
} else {
throw new Error("Failed to execute FLUSHALL on Redis")
}
})
})
21 changes: 21 additions & 0 deletions apps/dashboard/cypress/support/e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// ***********************************************************
// This example support/e2e.ts is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************

// Import commands.js using ES2015 syntax:
// eslint-disable-next-line import/no-unassigned-import
import "./commands"

// Alternatively you can use CommonJS syntax:
// require('./commands')
5 changes: 5 additions & 0 deletions apps/dashboard/cypress/support/test-data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const testData = {
NEXT_AUTH_SESSION_TOKEN: Cypress.env("NEXT_AUTH_SESSION_TOKEN"),
EMAIL: "test@galoy.io",
CALLBACK_URL: "https://www.google.com/",
}
Loading

0 comments on commit 5d900a1

Please sign in to comment.