From e46f2c32e30613221124d1338da33cd7d3e402cd Mon Sep 17 00:00:00 2001
From: Allen Zhou <46854522+allenzhou101@users.noreply.github.com>
Date: Sun, 9 Jul 2023 19:34:30 +0900
Subject: [PATCH 1/7] Add Descope doc to testing strategies
---
.../descope-authentication.mdx | 310 ++++++++++++++++++
1 file changed, 310 insertions(+)
create mode 100644 docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx
diff --git a/docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx b/docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx
new file mode 100644
index 0000000000..2e69e55a08
--- /dev/null
+++ b/docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx
@@ -0,0 +1,310 @@
+---
+title: Descope Authentication
+slug: /guides/end-to-end-testing/descope-authentication
+---
+
+:::info
+
+## What you'll learn
+
+- Log in to [Descope](https://descope.com) through the UI
+- Programmatically authenticate with [Descope](https://descope.com) via a custom
+ Cypress command
+- Adapt your [Descope](https://descope.com) application for programmatic
+ authentication during testing
+
+:::
+
+## Descope Application Setup
+
+To get started with Descope, an application needs to be setup within the
+[Descope Dashboard](https://app.descope.com/home) via the following steps:
+
+1. Visit the [Descope Dashboard](https://app.descope.com/home) and click the
+ "+ Project" button under the project dropdown.
+2. Enter the desired name for your application.
+3. Hit the "Create" button
+
+## Setting Descope app credentials in Cypress
+
+To have access to test user credentials within our tests we need to configure
+Cypress to use the [Descope](https://descope.com) environment variables set in the
+`.env` file.
+
+:::cypress-config-example
+
+```js
+// Populate process.env with values from .env file
+require('dotenv').config()
+```
+
+```js
+{
+ e2e: {
+ includeShadowDom: true, // For interacting with Descope components
+ },
+ env: {
+ descope_project_id: process.env.REACT_APP_DESCOPE_PROJECT_ID,
+ descope_management_key: process.env.REACT_APP_DESCOPE_MANAGEMENT_KEY
+ },
+}
+```
+
+:::
+
+## Custom Command for Descope Authentication
+
+There are two ways you can authenticate to Descope:
+
+- [Login with UI](#Login-with-UI)
+- [Programmatic Login](#Programmatic-Login)
+
+## Initialize test user
+For both UI and programatic login, you'll need to initialize a test user.
+
+```js
+const projectId = Cypress.env('descope_project_id')
+const managementKey = Cypress.env('descope_management_key')
+const descopeAPIDomain = "api.descope.com"
+
+// Define the authorization header
+const authHeader = {
+ 'Authorization': `Bearer ${projectId}:${managementKey}`,
+}
+
+// Define the base URL for Descope API
+const descopeApiBaseURL = `https://${descopeAPIDomain}/v1`;
+
+const testUserLoginId = "testUser" + Math.floor(1000 + Math.random() * 9000) + "@gmail.com"; // Must match email to pass validation
+
+// Define the test user details
+const testUser = {
+ loginId: testUserLoginId,
+ email: testUserLoginId,
+ phone: "+11231231234",
+ verifiedEmail: true,
+ verifiedPhone: true,
+ displayName: "Test User",
+ test: true,
+}
+```
+
+### Login with UI
+
+Next, we'll write a custom command called `loginToDescope` to perform a login to
+[Descope](https://descope.com) using the [Test User Management API](https://docs.descope.com/api/testusermanagement/)
+ and navigating via the user interface. This command will
+
+1. Navigate to the Descope login
+2. Input user credentials
+3. Sign in
+4. Cache the results with [`cy.session()`](/api/commands/session)
+
+```js
+// cypress/support/auth-provider-commands/descope.ts
+
+function loginViaDescopeUi() {
+ // App landing page redirects to Auth0.
+ cy.visit('/')
+
+ // Login on Auth0.
+ cy.origin(
+ Cypress.env('auth0_domain'),
+ { args: { username, password } },
+ ({ username, password }) => {
+ cy.get('input#username').type(username)
+ cy.get('input#password').type(password, { log: false })
+ cy.contains('button[value=default]', 'Continue').click()
+ }
+ )
+
+ // Ensure Auth0 has redirected us back to the RWA.
+ cy.url().should('equal', 'http://localhost:3000/')
+}
+
+Cypress.Commands.add('loginToAuth0', () => {
+ const log = Cypress.log({
+ displayName: 'Descope LOGIN',
+ message: [`🔐 Authenticating | ${username}`],
+ // @ts-ignore
+ autoEnd: false,
+ })
+ log.snapshot('before')
+
+ loginViaAuth0Ui(username, password)
+
+ log.snapshot('after')
+ log.end()
+})
+```
+
+Now, we can use our `loginToAuth0` command in the test. Below is our test to
+login as a user via Auth0 and run a basic sanity check.
+
+:::tip
+
+The
+[runnable version of this test](https://github.com/cypress-io/cypress-realworld-app/blob/develop/cypress/tests/ui-auth-providers/auth0.spec.ts)
+is in the
+[Cypress Real World App](https://github.com/cypress-io/cypress-realworld-app).
+
+:::
+
+```js
+describe('Auth0', function () {
+ beforeEach(function () {
+ cy.task('db:seed')
+ cy.intercept('POST', '/graphql').as('createBankAccount')
+ cy.loginToAuth0(
+ Cypress.env('auth0_username'),
+ Cypress.env('auth0_password')
+ )
+ cy.visit('/')
+ })
+
+ it('shows onboarding', function () {
+ cy.contains('Get Started').should('be.visible')
+ })
+})
+```
+
+
+
+Lastly, we can refactor our login command to take advantage of
+[`cy.session()`](/api/commands/session) to store our logged in user so we don't
+have to reauthenticate before every test.
+
+```js
+Cypress.Commands.add('loginToAuth0', (username: string, password: string) => {
+ const log = Cypress.log({
+ displayName: 'AUTH0 LOGIN',
+ message: [`🔐 Authenticating | ${username}`],
+ // @ts-ignore
+ autoEnd: false,
+ })
+ log.snapshot('before')
+
+ cy.session(
+ `auth0-${username}`,
+ () => {
+ loginViaAuth0Ui(username, password)
+ },
+ {
+ validate: () => {
+ // Validate presence of access token in localStorage.
+ cy.wrap(localStorage)
+ .invoke('getItem', 'authAccessToken')
+ .should('exist')
+ },
+ }
+ )
+
+ log.snapshot('after')
+ log.end()
+})
+```
+
+
+
+### Programmatic Login
+
+Below is a command to programmatically login into [Auth0](https://auth0.com),
+using the
+[/oauth/token endpoint](https://auth0.com/docs/protocols/protocol-oauth2#token-endpoint)
+and set an item in `localStorage` with the authenticated users details, which we
+will use in our application code to verify we are authenticated under test.
+
+The `loginByAuth0Api` command will execute the following steps:
+
+1. Use the
+ [/oauth/token endpoint](https://auth0.com/docs/protocols/protocol-oauth2#token-endpoint)
+ to perform the programmatic login.
+2. Finally the `auth0Cypress` `localStorage` item is set with the
+ `access token`, `id_token` and user profile.
+
+```jsx
+// cypress/support/commands.js
+Cypress.Commands.add(
+ 'loginByAuth0Api',
+ (username: string, password: string) => {
+ cy.log(`Logging in as ${username}`)
+ const client_id = Cypress.env('auth0_client_id')
+ const client_secret = Cypress.env('auth0_client_secret')
+ const audience = Cypress.env('auth0_audience')
+ const scope = Cypress.env('auth0_scope')
+
+ cy.request({
+ method: 'POST',
+ url: `https://${Cypress.env('auth0_domain')}/oauth/token`,
+ body: {
+ grant_type: 'password',
+ username,
+ password,
+ audience,
+ scope,
+ client_id,
+ client_secret,
+ },
+ }).then(({ body }) => {
+ const claims = jwt.decode(body.id_token)
+ const {
+ nickname,
+ name,
+ picture,
+ updated_at,
+ email,
+ email_verified,
+ sub,
+ exp,
+ } = claims
+
+ const item = {
+ body: {
+ ...body,
+ decodedToken: {
+ claims,
+ user: {
+ nickname,
+ name,
+ picture,
+ updated_at,
+ email,
+ email_verified,
+ sub,
+ },
+ audience,
+ client_id,
+ },
+ },
+ expiresAt: exp,
+ }
+
+ window.localStorage.setItem('auth0Cypress', JSON.stringify(item))
+
+ cy.visit('/')
+ })
+ }
+)
+```
+
+With our Auth0 app setup properly in the Auth0 Developer console, necessary
+environment variables in place, and our `loginByAuth0Api` command implemented,
+we will be able to authenticate with Auth0 while our app is under test. Below is
+a test to login as a user via [Auth0](https://auth0.com), complete the
+onboarding process and logout.
+
+```jsx
+describe('Auth0', function () {
+ beforeEach(function () {
+ cy.task('db:seed')
+ cy.loginByAuth0Api(
+ Cypress.env('auth0_username'),
+ Cypress.env('auth0_password')
+ )
+ })
+
+ it('shows onboarding', function () {
+ cy.contains('Get Started').should('be.visible')
+ })
+})
+```
From 4144e91feb1ed8d0c39d95f8c2a6899d8b7865ad Mon Sep 17 00:00:00 2001
From: Allen Zhou <46854522+allenzhou101@users.noreply.github.com>
Date: Sun, 9 Jul 2023 19:50:16 +0900
Subject: [PATCH 2/7] Update descope-authentication.mdx
---
.../testing-strategies/descope-authentication.mdx | 6 ------
1 file changed, 6 deletions(-)
diff --git a/docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx b/docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx
index 2e69e55a08..daa488bd7b 100644
--- a/docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx
+++ b/docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx
@@ -10,8 +10,6 @@ slug: /guides/end-to-end-testing/descope-authentication
- Log in to [Descope](https://descope.com) through the UI
- Programmatically authenticate with [Descope](https://descope.com) via a custom
Cypress command
-- Adapt your [Descope](https://descope.com) application for programmatic
- authentication during testing
:::
@@ -168,8 +166,6 @@ describe('Auth0', function () {
})
```
-
-
Lastly, we can refactor our login command to take advantage of
[`cy.session()`](/api/commands/session) to store our logged in user so we don't
have to reauthenticate before every test.
@@ -204,8 +200,6 @@ Cypress.Commands.add('loginToAuth0', (username: string, password: string) => {
})
```
-
-
### Programmatic Login
Below is a command to programmatically login into [Auth0](https://auth0.com),
From 5f2ff02387387c8a42c094740a0e2f2ef8a56118 Mon Sep 17 00:00:00 2001
From: Allen Zhou <46854522+allenzhou101@users.noreply.github.com>
Date: Mon, 10 Jul 2023 18:24:16 +0900
Subject: [PATCH 3/7] Update descope-authentication.mdx
---
.../descope-authentication.mdx | 312 ++++++++----------
1 file changed, 136 insertions(+), 176 deletions(-)
diff --git a/docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx b/docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx
index daa488bd7b..58d74b6756 100644
--- a/docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx
+++ b/docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx
@@ -57,10 +57,13 @@ There are two ways you can authenticate to Descope:
- [Login with UI](#Login-with-UI)
- [Programmatic Login](#Programmatic-Login)
-## Initialize test user
-For both UI and programatic login, you'll need to initialize a test user.
+### Initialize test user & variables
+For both UI and programatic login, you'll need to initialize a test user and get your env variables.
+We'll do this in the `cypress/support/commands.js` file.
```js
+// cypress/support/commands.js
+
const projectId = Cypress.env('descope_project_id')
const managementKey = Cypress.env('descope_management_key')
const descopeAPIDomain = "api.descope.com"
@@ -87,218 +90,175 @@ const testUser = {
}
```
+We’ll also need to clean up the created testing users before starting so we don’t go over the limit.
+This is done with the `deleteAllTestUsers` function.
+```js
+// cypress/support/commands.js
+
+Cypress.Commands.add('deleteAllTestUsers', () => {
+ cy.request({
+ method: 'DELETE',
+ url: `${descopeApiBaseURL}/mgmt/user/test/delete/all`,
+ headers: authHeader,
+ })
+})
+```
+
+
### Login with UI
-Next, we'll write a custom command called `loginToDescope` to perform a login to
+Next, we'll write a custom command called `loginViaDescopeUI` to perform a login to
[Descope](https://descope.com) using the [Test User Management API](https://docs.descope.com/api/testusermanagement/)
and navigating via the user interface. This command will
1. Navigate to the Descope login
-2. Input user credentials
-3. Sign in
-4. Cache the results with [`cy.session()`](/api/commands/session)
+2. Use the [Test User Management API](https://docs.descope.com/api/testusermanagement/) to perform the login (create user and generate OTP code).
+3. Enter the user loginId and code that we just generated to log in via the user interface.
```js
-// cypress/support/auth-provider-commands/descope.ts
-
-function loginViaDescopeUi() {
- // App landing page redirects to Auth0.
- cy.visit('/')
-
- // Login on Auth0.
- cy.origin(
- Cypress.env('auth0_domain'),
- { args: { username, password } },
- ({ username, password }) => {
- cy.get('input#username').type(username)
- cy.get('input#password').type(password, { log: false })
- cy.contains('button[value=default]', 'Continue').click()
- }
- )
-
- // Ensure Auth0 has redirected us back to the RWA.
- cy.url().should('equal', 'http://localhost:3000/')
-}
-
-Cypress.Commands.add('loginToAuth0', () => {
- const log = Cypress.log({
- displayName: 'Descope LOGIN',
- message: [`🔐 Authenticating | ${username}`],
- // @ts-ignore
- autoEnd: false,
- })
- log.snapshot('before')
-
- loginViaAuth0Ui(username, password)
+// cypress/support/commands.js
- log.snapshot('after')
- log.end()
+Cypress.Commands.add('loginViaDescopeUI', () => {
+ cy.request({
+ method: 'POST',
+ url: `${descopeApiBaseURL}/mgmt/user/create`,
+ headers: authHeader,
+ body: testUser,
+ })
+ .then(({ body }) => {
+ const loginId = body["user"]["loginIds"][0];
+ cy.request({
+ method: 'POST',
+ url: `${descopeApiBaseURL}/mgmt/tests/generate/otp`,
+ headers: authHeader,
+ body: {
+ "loginId": loginId,
+ "deliveryMethod": "email"
+ }
+ })
+ .then(({ body }) => {
+ const otpCode = body["code"]
+ const loginID = body["loginId"]
+ cy.visit('/login')
+ cy.get('descope-wc')
+ .find('input')
+ .type(loginID)
+ cy.get('descope-wc')
+ .find('button').contains('Continue').click()
+ cy.get('descope-wc').find('.descope-input-wrapper').find('input').should('exist') // Assertion added to wait for the OTP code input to appear
+ let otpCodeArray = Array.from(otpCode); // Convert the OTP code string to an array
+ for (var i = 0; i < otpCodeArray.length; i++) {
+ cy.get('descope-wc').find('.descope-input-wrapper').find('input').eq(i + 1).type(otpCodeArray[i], { force: true })
+ }
+ cy.get('descope-wc')
+ .find('button').contains('Submit').click()
+
+ // Customize these steps based on your authentication flow
+ })
+ })
})
```
-Now, we can use our `loginToAuth0` command in the test. Below is our test to
-login as a user via Auth0 and run a basic sanity check.
-
-:::tip
-
-The
-[runnable version of this test](https://github.com/cypress-io/cypress-realworld-app/blob/develop/cypress/tests/ui-auth-providers/auth0.spec.ts)
-is in the
-[Cypress Real World App](https://github.com/cypress-io/cypress-realworld-app).
-
-:::
+Now, we can use our `loginViaDescopeUI` command in the test. Below is our test to
+login as a user via Descope and run a basic sanity check.
```js
-describe('Auth0', function () {
+describe('Descope', function () {
beforeEach(function () {
- cy.task('db:seed')
- cy.intercept('POST', '/graphql').as('createBankAccount')
- cy.loginToAuth0(
- Cypress.env('auth0_username'),
- Cypress.env('auth0_password')
- )
- cy.visit('/')
+ cy.deleteAllTestUsers()
+ cy.loginViaDescopeUI()
+ cy.visit('/')
})
- it('shows onboarding', function () {
- cy.contains('Get Started').should('be.visible')
+ it('shows welcome page', function () {
+ cy.contains('Welcome').should('be.visible')
})
})
```
-Lastly, we can refactor our login command to take advantage of
-[`cy.session()`](/api/commands/session) to store our logged in user so we don't
-have to reauthenticate before every test.
-
-```js
-Cypress.Commands.add('loginToAuth0', (username: string, password: string) => {
- const log = Cypress.log({
- displayName: 'AUTH0 LOGIN',
- message: [`🔐 Authenticating | ${username}`],
- // @ts-ignore
- autoEnd: false,
- })
- log.snapshot('before')
-
- cy.session(
- `auth0-${username}`,
- () => {
- loginViaAuth0Ui(username, password)
- },
- {
- validate: () => {
- // Validate presence of access token in localStorage.
- cy.wrap(localStorage)
- .invoke('getItem', 'authAccessToken')
- .should('exist')
- },
- }
- )
-
- log.snapshot('after')
- log.end()
-})
-```
-
### Programmatic Login
-Below is a command to programmatically login into [Auth0](https://auth0.com),
-using the
-[/oauth/token endpoint](https://auth0.com/docs/protocols/protocol-oauth2#token-endpoint)
+We'll now write a command to programmatically login into
+[Descope](https://descope.com) using the [Test User Management API](https://docs.descope.com/api/testusermanagement/)
and set an item in `localStorage` with the authenticated users details, which we
will use in our application code to verify we are authenticated under test.
-The `loginByAuth0Api` command will execute the following steps:
+The `loginViaDescopeApi` command will execute the following steps:
+
+1. Use the [Test User Management API](https://docs.descope.com/api/testusermanagement/) to perform the programmatic login (create user, generate OTP code, and verify OTP code).
+2. Set the `refreshToken` and `sessionToken` items in localStorage.
-1. Use the
- [/oauth/token endpoint](https://auth0.com/docs/protocols/protocol-oauth2#token-endpoint)
- to perform the programmatic login.
-2. Finally the `auth0Cypress` `localStorage` item is set with the
- `access token`, `id_token` and user profile.
```jsx
// cypress/support/commands.js
-Cypress.Commands.add(
- 'loginByAuth0Api',
- (username: string, password: string) => {
- cy.log(`Logging in as ${username}`)
- const client_id = Cypress.env('auth0_client_id')
- const client_secret = Cypress.env('auth0_client_secret')
- const audience = Cypress.env('auth0_audience')
- const scope = Cypress.env('auth0_scope')
-
+Cypress.Commands.add('loginViaDescopeAPI', () => {
cy.request({
- method: 'POST',
- url: `https://${Cypress.env('auth0_domain')}/oauth/token`,
- body: {
- grant_type: 'password',
- username,
- password,
- audience,
- scope,
- client_id,
- client_secret,
- },
- }).then(({ body }) => {
- const claims = jwt.decode(body.id_token)
- const {
- nickname,
- name,
- picture,
- updated_at,
- email,
- email_verified,
- sub,
- exp,
- } = claims
-
- const item = {
- body: {
- ...body,
- decodedToken: {
- claims,
- user: {
- nickname,
- name,
- picture,
- updated_at,
- email,
- email_verified,
- sub,
- },
- audience,
- client_id,
- },
- },
- expiresAt: exp,
- }
-
- window.localStorage.setItem('auth0Cypress', JSON.stringify(item))
-
- cy.visit('/')
+ method: 'POST',
+ url: `${descopeApiBaseURL}/mgmt/user/create`,
+ headers: authHeader,
+ body: testUser,
})
- }
-)
+ .then(({ body }) => {
+ const loginId = body["user"]["loginIds"][0];
+ cy.request({
+ method: 'POST',
+ url: `${descopeApiBaseURL}/mgmt/tests/generate/otp`,
+ headers: authHeader,
+ body: {
+ "loginId": loginId,
+ "deliveryMethod": "email"
+ }
+ })
+ .then(({ body }) => {
+ const otpCode = body["code"]
+ cy.request({
+ method: 'POST',
+ url: `${descopeApiBaseURL}/auth/otp/verify/email`,
+ headers: authHeader,
+ body: {
+ "loginId": loginId,
+ "code": otpCode
+ }
+ })
+ .then(({ body }) => {
+ const sessionJwt = body["sessionJwt"]
+ const refreshJwt = body["refreshJwt"]
+
+ /** Default name for the session cookie name / local storage key */
+ const SESSION_TOKEN_KEY = 'DS';
+ /** Default name for the refresh local storage key */
+ const REFRESH_TOKEN_KEY = 'DSR';
+
+ // // Store the JWT in the browser's local storage.
+ cy.window().then((win) => {
+ win.localStorage.setItem(SESSION_TOKEN_KEY, sessionJwt);
+ win.localStorage.setItem(REFRESH_TOKEN_KEY, refreshJwt);
+ });
+
+ // // Now navigate to the root URL of your application.
+ cy.visit('/')
+
+ })
+ })
+ })
+})
```
-With our Auth0 app setup properly in the Auth0 Developer console, necessary
-environment variables in place, and our `loginByAuth0Api` command implemented,
-we will be able to authenticate with Auth0 while our app is under test. Below is
-a test to login as a user via [Auth0](https://auth0.com), complete the
-onboarding process and logout.
+With our Descope app setup properly in the Descope Developer console,
+necessary environment variables in place, and our
+`loginViaDescopeApi` command implemented, we will be able to authenticate
+ with Descope while our app is under test. Below is
+ a test to login as a user using our loginViaDescopeAPI function and verify the welcome page is showing.
```jsx
-describe('Auth0', function () {
+describe('Descope', function () {
beforeEach(function () {
- cy.task('db:seed')
- cy.loginByAuth0Api(
- Cypress.env('auth0_username'),
- Cypress.env('auth0_password')
- )
+ cy.deleteAllTestUsers()
+ cy.loginViaDescopeAPI()
})
- it('shows onboarding', function () {
- cy.contains('Get Started').should('be.visible')
- })
+ it('shows welcome page', function () {
+ cy.contains('Welcome').should('be.visible')
+ })
})
```
From c2d433b0f7218150ce64992fb8956fd130473d0f Mon Sep 17 00:00:00 2001
From: Allen Zhou <46854522+allenzhou101@users.noreply.github.com>
Date: Mon, 10 Jul 2023 18:24:29 +0900
Subject: [PATCH 4/7] Update descope-authentication.mdx
---
.../testing-strategies/descope-authentication.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx b/docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx
index 58d74b6756..a61e5f2a6b 100644
--- a/docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx
+++ b/docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx
@@ -90,7 +90,7 @@ const testUser = {
}
```
-We’ll also need to clean up the created testing users before starting so we don’t go over the limit.
+We’ll also need to clean up the created test users before starting so we don’t go over the limit.
This is done with the `deleteAllTestUsers` function.
```js
// cypress/support/commands.js
From e7107ed57b68a9dffdeca98632591aaa08e907e7 Mon Sep 17 00:00:00 2001
From: Allen Zhou <46854522+allenzhou101@users.noreply.github.com>
Date: Mon, 10 Jul 2023 18:27:48 +0900
Subject: [PATCH 5/7] Update descope-authentication.mdx
---
.../descope-authentication.mdx | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx b/docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx
index a61e5f2a6b..b3b74715d5 100644
--- a/docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx
+++ b/docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx
@@ -7,7 +7,7 @@ slug: /guides/end-to-end-testing/descope-authentication
## What you'll learn
-- Log in to [Descope](https://descope.com) through the UI
+- Log in to [Descope](https://descope.com) via the UI
- Programmatically authenticate with [Descope](https://descope.com) via a custom
Cypress command
@@ -58,7 +58,7 @@ There are two ways you can authenticate to Descope:
- [Programmatic Login](#Programmatic-Login)
### Initialize test user & variables
-For both UI and programatic login, you'll need to initialize a test user and get your env variables.
+For both UI and programatic login, you'll need to initialize a test user, get your env variables, and create a delete users command.
We'll do this in the `cypress/support/commands.js` file.
```js
@@ -90,8 +90,8 @@ const testUser = {
}
```
-We’ll also need to clean up the created test users before starting so we don’t go over the limit.
-This is done with the `deleteAllTestUsers` function.
+To clean up the created test users so we don’t go over the test user limit,
+we'll have a `deleteAllTestUsers` function.
```js
// cypress/support/commands.js
@@ -113,7 +113,7 @@ Next, we'll write a custom command called `loginViaDescopeUI` to perform a login
1. Navigate to the Descope login
2. Use the [Test User Management API](https://docs.descope.com/api/testusermanagement/) to perform the login (create user and generate OTP code).
-3. Enter the user loginId and code that we just generated to log in via the user interface.
+3. Enter the user login ID and code that we just generated to log in via the user interface.
```js
// cypress/support/commands.js
@@ -183,7 +183,7 @@ We'll now write a command to programmatically login into
and set an item in `localStorage` with the authenticated users details, which we
will use in our application code to verify we are authenticated under test.
-The `loginViaDescopeApi` command will execute the following steps:
+The `loginViaDescopeAPI` command will execute the following steps:
1. Use the [Test User Management API](https://docs.descope.com/api/testusermanagement/) to perform the programmatic login (create user, generate OTP code, and verify OTP code).
2. Set the `refreshToken` and `sessionToken` items in localStorage.
@@ -246,9 +246,9 @@ Cypress.Commands.add('loginViaDescopeAPI', () => {
With our Descope app setup properly in the Descope Developer console,
necessary environment variables in place, and our
-`loginViaDescopeApi` command implemented, we will be able to authenticate
+`loginViaDescopeAPI` command implemented, we will be able to authenticate
with Descope while our app is under test. Below is
- a test to login as a user using our loginViaDescopeAPI function and verify the welcome page is showing.
+ a test to login as a user using our `loginViaDescopeAPI` function and verify the welcome page is showing.
```jsx
describe('Descope', function () {
From 369ab58fb237a5468302f51e378d86f0b9614229 Mon Sep 17 00:00:00 2001
From: Allen Zhou <46854522+allenzhou101@users.noreply.github.com>
Date: Mon, 10 Jul 2023 18:37:44 +0900
Subject: [PATCH 6/7] Make page "Prettier"
---
.../descope-authentication.mdx | 212 +++++++++---------
1 file changed, 105 insertions(+), 107 deletions(-)
diff --git a/docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx b/docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx
index b3b74715d5..e7c2b47dc1 100644
--- a/docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx
+++ b/docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx
@@ -58,7 +58,8 @@ There are two ways you can authenticate to Descope:
- [Programmatic Login](#Programmatic-Login)
### Initialize test user & variables
-For both UI and programatic login, you'll need to initialize a test user, get your env variables, and create a delete users command.
+
+For both UI and programatic login, you'll need to initialize a test user, get your env variables, and create a delete users command.
We'll do this in the `cypress/support/commands.js` file.
```js
@@ -66,50 +67,51 @@ We'll do this in the `cypress/support/commands.js` file.
const projectId = Cypress.env('descope_project_id')
const managementKey = Cypress.env('descope_management_key')
-const descopeAPIDomain = "api.descope.com"
+const descopeAPIDomain = 'api.descope.com'
// Define the authorization header
const authHeader = {
- 'Authorization': `Bearer ${projectId}:${managementKey}`,
+ Authorization: `Bearer ${projectId}:${managementKey}`,
}
// Define the base URL for Descope API
-const descopeApiBaseURL = `https://${descopeAPIDomain}/v1`;
+const descopeApiBaseURL = `https://${descopeAPIDomain}/v1`
-const testUserLoginId = "testUser" + Math.floor(1000 + Math.random() * 9000) + "@gmail.com"; // Must match email to pass validation
+const testUserLoginId =
+ 'testUser' + Math.floor(1000 + Math.random() * 9000) + '@gmail.com' // Must match email to pass validation
// Define the test user details
const testUser = {
- loginId: testUserLoginId,
- email: testUserLoginId,
- phone: "+11231231234",
- verifiedEmail: true,
- verifiedPhone: true,
- displayName: "Test User",
- test: true,
+ loginId: testUserLoginId,
+ email: testUserLoginId,
+ phone: '+11231231234',
+ verifiedEmail: true,
+ verifiedPhone: true,
+ displayName: 'Test User',
+ test: true,
}
```
To clean up the created test users so we don’t go over the test user limit,
we'll have a `deleteAllTestUsers` function.
+
```js
// cypress/support/commands.js
Cypress.Commands.add('deleteAllTestUsers', () => {
- cy.request({
- method: 'DELETE',
- url: `${descopeApiBaseURL}/mgmt/user/test/delete/all`,
- headers: authHeader,
- })
+ cy.request({
+ method: 'DELETE',
+ url: `${descopeApiBaseURL}/mgmt/user/test/delete/all`,
+ headers: authHeader,
+ })
})
```
-
### Login with UI
Next, we'll write a custom command called `loginViaDescopeUI` to perform a login to
[Descope](https://descope.com) using the [Test User Management API](https://docs.descope.com/api/testusermanagement/)
- and navigating via the user interface. This command will
+and navigating via the user interface. This command will
1. Navigate to the Descope login
2. Use the [Test User Management API](https://docs.descope.com/api/testusermanagement/) to perform the login (create user and generate OTP code).
@@ -119,43 +121,44 @@ Next, we'll write a custom command called `loginViaDescopeUI` to perform a login
// cypress/support/commands.js
Cypress.Commands.add('loginViaDescopeUI', () => {
+ cy.request({
+ method: 'POST',
+ url: `${descopeApiBaseURL}/mgmt/user/create`,
+ headers: authHeader,
+ body: testUser,
+ }).then(({ body }) => {
+ const loginId = body['user']['loginIds'][0]
cy.request({
- method: 'POST',
- url: `${descopeApiBaseURL}/mgmt/user/create`,
- headers: authHeader,
- body: testUser,
+ method: 'POST',
+ url: `${descopeApiBaseURL}/mgmt/tests/generate/otp`,
+ headers: authHeader,
+ body: {
+ loginId: loginId,
+ deliveryMethod: 'email',
+ },
+ }).then(({ body }) => {
+ const otpCode = body['code']
+ const loginID = body['loginId']
+ cy.visit('/login')
+ cy.get('descope-wc').find('input').type(loginID)
+ cy.get('descope-wc').find('button').contains('Continue').click()
+ cy.get('descope-wc')
+ .find('.descope-input-wrapper')
+ .find('input')
+ .should('exist') // Assertion added to wait for the OTP code input to appear
+ let otpCodeArray = Array.from(otpCode) // Convert the OTP code string to an array
+ for (var i = 0; i < otpCodeArray.length; i++) {
+ cy.get('descope-wc')
+ .find('.descope-input-wrapper')
+ .find('input')
+ .eq(i + 1)
+ .type(otpCodeArray[i], { force: true })
+ }
+ cy.get('descope-wc').find('button').contains('Submit').click()
+
+ // Customize these steps based on your authentication flow
})
- .then(({ body }) => {
- const loginId = body["user"]["loginIds"][0];
- cy.request({
- method: 'POST',
- url: `${descopeApiBaseURL}/mgmt/tests/generate/otp`,
- headers: authHeader,
- body: {
- "loginId": loginId,
- "deliveryMethod": "email"
- }
- })
- .then(({ body }) => {
- const otpCode = body["code"]
- const loginID = body["loginId"]
- cy.visit('/login')
- cy.get('descope-wc')
- .find('input')
- .type(loginID)
- cy.get('descope-wc')
- .find('button').contains('Continue').click()
- cy.get('descope-wc').find('.descope-input-wrapper').find('input').should('exist') // Assertion added to wait for the OTP code input to appear
- let otpCodeArray = Array.from(otpCode); // Convert the OTP code string to an array
- for (var i = 0; i < otpCodeArray.length; i++) {
- cy.get('descope-wc').find('.descope-input-wrapper').find('input').eq(i + 1).type(otpCodeArray[i], { force: true })
- }
- cy.get('descope-wc')
- .find('button').contains('Submit').click()
-
- // Customize these steps based on your authentication flow
- })
- })
+ })
})
```
@@ -167,7 +170,7 @@ describe('Descope', function () {
beforeEach(function () {
cy.deleteAllTestUsers()
cy.loginViaDescopeUI()
- cy.visit('/')
+ cy.visit('/')
})
it('shows welcome page', function () {
@@ -178,7 +181,7 @@ describe('Descope', function () {
### Programmatic Login
-We'll now write a command to programmatically login into
+We'll now write a command to programmatically login into
[Descope](https://descope.com) using the [Test User Management API](https://docs.descope.com/api/testusermanagement/)
and set an item in `localStorage` with the authenticated users details, which we
will use in our application code to verify we are authenticated under test.
@@ -188,67 +191,62 @@ The `loginViaDescopeAPI` command will execute the following steps:
1. Use the [Test User Management API](https://docs.descope.com/api/testusermanagement/) to perform the programmatic login (create user, generate OTP code, and verify OTP code).
2. Set the `refreshToken` and `sessionToken` items in localStorage.
-
```jsx
// cypress/support/commands.js
Cypress.Commands.add('loginViaDescopeAPI', () => {
+ cy.request({
+ method: 'POST',
+ url: `${descopeApiBaseURL}/mgmt/user/create`,
+ headers: authHeader,
+ body: testUser,
+ }).then(({ body }) => {
+ const loginId = body['user']['loginIds'][0]
cy.request({
+ method: 'POST',
+ url: `${descopeApiBaseURL}/mgmt/tests/generate/otp`,
+ headers: authHeader,
+ body: {
+ loginId: loginId,
+ deliveryMethod: 'email',
+ },
+ }).then(({ body }) => {
+ const otpCode = body['code']
+ cy.request({
method: 'POST',
- url: `${descopeApiBaseURL}/mgmt/user/create`,
+ url: `${descopeApiBaseURL}/auth/otp/verify/email`,
headers: authHeader,
- body: testUser,
- })
- .then(({ body }) => {
- const loginId = body["user"]["loginIds"][0];
- cy.request({
- method: 'POST',
- url: `${descopeApiBaseURL}/mgmt/tests/generate/otp`,
- headers: authHeader,
- body: {
- "loginId": loginId,
- "deliveryMethod": "email"
- }
- })
- .then(({ body }) => {
- const otpCode = body["code"]
- cy.request({
- method: 'POST',
- url: `${descopeApiBaseURL}/auth/otp/verify/email`,
- headers: authHeader,
- body: {
- "loginId": loginId,
- "code": otpCode
- }
- })
- .then(({ body }) => {
- const sessionJwt = body["sessionJwt"]
- const refreshJwt = body["refreshJwt"]
-
- /** Default name for the session cookie name / local storage key */
- const SESSION_TOKEN_KEY = 'DS';
- /** Default name for the refresh local storage key */
- const REFRESH_TOKEN_KEY = 'DSR';
-
- // // Store the JWT in the browser's local storage.
- cy.window().then((win) => {
- win.localStorage.setItem(SESSION_TOKEN_KEY, sessionJwt);
- win.localStorage.setItem(REFRESH_TOKEN_KEY, refreshJwt);
- });
-
- // // Now navigate to the root URL of your application.
- cy.visit('/')
-
- })
- })
+ body: {
+ loginId: loginId,
+ code: otpCode,
+ },
+ }).then(({ body }) => {
+ const sessionJwt = body['sessionJwt']
+ const refreshJwt = body['refreshJwt']
+
+ /** Default name for the session cookie name / local storage key */
+ const SESSION_TOKEN_KEY = 'DS'
+ /** Default name for the refresh local storage key */
+ const REFRESH_TOKEN_KEY = 'DSR'
+
+ // // Store the JWT in the browser's local storage.
+ cy.window().then((win) => {
+ win.localStorage.setItem(SESSION_TOKEN_KEY, sessionJwt)
+ win.localStorage.setItem(REFRESH_TOKEN_KEY, refreshJwt)
})
+
+ // // Now navigate to the root URL of your application.
+ cy.visit('/')
+ })
+ })
+ })
})
```
-With our Descope app setup properly in the Descope Developer console,
-necessary environment variables in place, and our
+With our Descope app setup properly in the Descope Developer console,
+necessary environment variables in place, and our
`loginViaDescopeAPI` command implemented, we will be able to authenticate
- with Descope while our app is under test. Below is
- a test to login as a user using our `loginViaDescopeAPI` function and verify the welcome page is showing.
+with Descope while our app is under test. Below is
+a test to login as a user using our `loginViaDescopeAPI` function and verify the welcome page is showing.
```jsx
describe('Descope', function () {
@@ -259,6 +257,6 @@ describe('Descope', function () {
it('shows welcome page', function () {
cy.contains('Welcome').should('be.visible')
- })
+ })
})
```
From 7e0fb6276a8885fc7fecf2d595d1be2f4aa3ca6d Mon Sep 17 00:00:00 2001
From: Allen Zhou <46854522+allenzhou101@users.noreply.github.com>
Date: Mon, 23 Dec 2024 14:19:21 -0600
Subject: [PATCH 7/7] Move Descope Authentication Guide to App folder
---
.../guides/authentication-testing}/descope-authentication.mdx | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename docs/{guides/end-to-end-testing/testing-strategies => app/guides/authentication-testing}/descope-authentication.mdx (100%)
diff --git a/docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx b/docs/app/guides/authentication-testing/descope-authentication.mdx
similarity index 100%
rename from docs/guides/end-to-end-testing/testing-strategies/descope-authentication.mdx
rename to docs/app/guides/authentication-testing/descope-authentication.mdx