-
Notifications
You must be signed in to change notification settings - Fork 212
@W-18685522 Password Reset and Passwordless Integration Test #2669
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
jeremy-jung1
merged 53 commits into
develop
from
W-18685522-reset-and-passwordless-integration-test
Jul 8, 2025
Merged
Changes from 33 commits
Commits
Show all changes
53 commits
Select commit
Hold shift + click to select a range
c36c896
playwright tests
jeremy-jung1 cae80a9
variable name change
jeremy-jung1 98d6d75
Create ssr.test.js
jeremy-jung1 14519ee
fix the tests
jeremy-jung1 ef7c280
Update CHANGELOG.md
jeremy-jung1 f6940b0
Only keep tests relevant to the feature
jeremy-jung1 8b1397c
Remove unused vars
jeremy-jung1 de564d8
Merge branch 'develop' into W-18685522-reset-and-passwordless-integra…
jeremy-jung1 dceb6d9
Linting
jeremy-jung1 f108b78
More linting
jeremy-jung1 da85267
Try auto sync and deploy
jeremy-jung1 a2cbaf2
for some reason need to update the commerce-sdk-react changelog. will…
jeremy-jung1 d73e3c9
Try adding branch to dependency to test
jeremy-jung1 ecd734d
Try adding perms and removing notifications
jeremy-jung1 7203712
Go to template retail react app
jeremy-jung1 c1e5387
Update project slug
jeremy-jung1 f8ad75c
log some more info in push mrt
jeremy-jung1 9c24f62
Make some updates
jeremy-jung1 b11782f
Update yml file
jeremy-jung1 eb4a480
Change env name
jeremy-jung1 52cec86
Update branch name
jeremy-jung1 502faa0
Update variable
jeremy-jung1 5722000
Remove unnecessary changes
jeremy-jung1 07fe23e
Need to update changelog for some reason
jeremy-jung1 02fa18f
Testing issue creation
jeremy-jung1 4ee2253
Just testing
jeremy-jung1 b363136
Update sync_extra_features_e2e.yml
jeremy-jung1 f0e4e03
Add creation
jeremy-jung1 b3f5f21
Revert the tests
jeremy-jung1 ecd8171
Update message in issue creation
jeremy-jung1 d33ca67
Merge branch 'develop' into W-18685522-reset-and-passwordless-integra…
jeremy-jung1 6cc46e7
Remove this branch from dependency
jeremy-jung1 53f2dc1
Merge branch 'W-18685522-reset-and-passwordless-integration-test' of …
jeremy-jung1 1c96b6a
Remove force sync
jeremy-jung1 505f0af
Add tests for when extra login features are not enabled
jeremy-jung1 70247cf
Apply some feedback
jeremy-jung1 e3cfcb4
Update e2e.yml
jeremy-jung1 ec85ce8
Update command and comment some things for test
jeremy-jung1 f6d34f0
Update e2e.yml
jeremy-jung1 929d86c
Update e2e.yml
jeremy-jung1 10aa890
Try to insert these env vars
jeremy-jung1 2c94bc0
Apply feedback
jeremy-jung1 2ede681
Update playwright.config.js
jeremy-jung1 9909caa
Update separate mobile and desktop
jeremy-jung1 0ab3fde
typo
jeremy-jung1 6f59650
Fix the sites
jeremy-jung1 4caf056
Update config.js
jeremy-jung1 be5b871
Remove changes made for just testing
jeremy-jung1 e584cdd
Merge branch 'develop' into W-18685522-reset-and-passwordless-integra…
jeremy-jung1 9de4b67
Remove dev only change
jeremy-jung1 6395135
Merge branch 'develop' into W-18685522-reset-and-passwordless-integra…
jeremy-jung1 0123c9e
Merge branch 'develop' into W-18685522-reset-and-passwordless-integra…
jeremy-jung1 d3b026c
Merge branch 'develop' into W-18685522-reset-and-passwordless-integra…
jeremy-jung1 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,186 @@ | ||
| name: Sync More Logins E2E Branch with Develop | ||
|
|
||
| on: | ||
| # Trigger when develop branch is updated | ||
| push: | ||
| branches: | ||
| - develop | ||
| # Run daily at 11 PM PST (7 AM UTC) to catch any missed syncs | ||
| schedule: | ||
| - cron: '0 7 * * *' | ||
| # Allow manual triggering with options | ||
| workflow_dispatch: | ||
| inputs: | ||
| force_sync: | ||
| description: 'Force sync even if conflicts exist (overwrites E2E branch)' | ||
| required: false | ||
| default: false | ||
| type: boolean | ||
|
|
||
| permissions: | ||
| contents: write | ||
| issues: write | ||
| pull-requests: read | ||
|
|
||
| jobs: | ||
| sync-branch: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
|
|
||
| - name: Configure git | ||
| run: | | ||
| git config --global user.name ${{ secrets.GIT_CONFIG_USERNAME }} | ||
| git config --global user.email ${{ secrets.GIT_CONFIG_EMAIL }} | ||
|
|
||
| - name: Sync extra-features-e2e-branch with develop | ||
| id: sync | ||
| continue-on-error: true | ||
| run: | | ||
| set -e | ||
|
|
||
| # Fetch all branches | ||
| git fetch origin | ||
|
|
||
| # Check if the target branch exists | ||
| if ! git show-ref --verify --quiet refs/remotes/origin/extra-features-e2e-branch; then | ||
| echo "Branch extra-features-e2e-branch does not exist. Creating it from develop..." | ||
| git checkout -b extra-features-e2e-branch origin/develop | ||
| git push origin extra-features-e2e-branch | ||
| echo "✅ Created extra-features-e2e-branch branch from develop" | ||
| echo "status=created" >> $GITHUB_OUTPUT | ||
| exit 0 | ||
| fi | ||
|
|
||
| # Switch to the target branch | ||
| git checkout extra-features-e2e-branch | ||
| git reset --hard origin/extra-features-e2e-branch | ||
|
|
||
| # Check if we're already up to date | ||
| if git merge-base --is-ancestor origin/develop HEAD; then | ||
| echo "✅ extra-features-e2e-branch is already up to date with develop" | ||
| echo "status=up-to-date" >> $GITHUB_OUTPUT | ||
| exit 0 | ||
| fi | ||
|
|
||
| if [ "${{ github.event.inputs.force_sync }}" = "true" ]; then | ||
| echo "🔧 Force sync requested. Resetting to develop..." | ||
| git reset --hard origin/develop | ||
| git push --force origin extra-features-e2e-branch | ||
| echo "⚠️ Force synced extra-features-e2e-branch with develop (all conflicts overwritten)" | ||
| echo "status=force-synced" >> $GITHUB_OUTPUT | ||
| else | ||
| # Default merge strategy | ||
| if git merge origin/develop --no-edit; then | ||
| echo "✅ Successfully merged develop into extra-features-e2e-branch" | ||
| git push origin extra-features-e2e-branch | ||
| echo "status=merged" >> $GITHUB_OUTPUT | ||
| else | ||
| echo "❌ Merge conflicts detected!" | ||
| echo "📋 Files with conflicts:" | ||
| git diff --name-only --diff-filter=U || true | ||
| git merge --abort | ||
| echo "status=conflict" >> $GITHUB_OUTPUT | ||
| exit 1 | ||
| fi | ||
| fi | ||
|
|
||
| - name: Create conflict resolution issue | ||
| if: steps.sync.outputs.status == 'conflict' | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| script: | | ||
| const conflictFiles = `${{ steps.sync.outputs.conflict_files || 'Unknown files' }}`; | ||
| const issueBody = ` | ||
| ## 🚨 Automatic Sync Failed - Merge Conflicts Detected | ||
|
|
||
| Some features in PWA kit are defaulted to be off in \`develop\` branch (e.g. if they only work with private client). | ||
| Hence there is another site that has these features enabled that E2E tests of these extra features are run against. | ||
| The \`extra-features-e2e-branch\` is used for this site. | ||
|
|
||
| A job is run nightly to sync \`develop\` to \`extra-features-e2e-branch\` branch, but today this automatic sync from \`develop\` to \`extra-features-e2e-branch\` failed due to merge conflicts. | ||
|
|
||
| ### Conflicting Files: | ||
| \`\`\` | ||
| ${conflictFiles} | ||
| \`\`\` | ||
|
|
||
|
|
||
| ### Manual Resolution: | ||
| \`\`\`bash | ||
| git checkout extra-features-e2e-branch | ||
| git pull origin extra-features-e2e-branch | ||
| git merge develop | ||
| # Resolve conflicts manually | ||
| git add . | ||
| git commit -m "Resolve merge conflicts from develop" | ||
| git push origin extra-features-e2e-branch | ||
| \`\`\` | ||
|
|
||
| ### After resolving the conflicts, close this issue | ||
| `; | ||
|
|
||
| // Check if issue already exists | ||
| const existingIssues = await github.rest.issues.listForRepo({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| state: 'open', | ||
| labels: 'sync-conflict' | ||
| }); | ||
|
|
||
| if (existingIssues.data.length === 0) { | ||
| await github.rest.issues.create({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| title: '🚨 Extra Features E2E Branch Sync Conflict - Manual Resolution Required', | ||
| body: issueBody, | ||
| labels: ['sync-conflict', 'automation'] | ||
| }); | ||
| } | ||
|
|
||
| deploy: | ||
| needs: sync-branch | ||
| if: needs.sync-branch.outputs.status != 'conflict' && needs.sync-branch.outputs.status != 'up-to-date' | ||
| runs-on: ubuntu-latest | ||
| environment: extra-features-e2e | ||
|
|
||
| steps: | ||
| - name: Checkout extra-features-e2e-branch branch | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| ref: extra-features-e2e-branch | ||
|
|
||
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: 22 | ||
| cache: 'npm' | ||
|
|
||
| - name: Install Monorepo Dependencies | ||
| run: | | ||
| # Install node dependencies | ||
| node ./scripts/gtime.js monorepo_install npm ci | ||
|
|
||
| - name: Build project | ||
| run: | | ||
| cd packages/template-retail-react-app | ||
| npm run build | ||
|
|
||
| - name: Create MRT credentials file | ||
| uses: "./.github/actions/create_mrt" | ||
| with: | ||
| mobify_user: ${{ secrets.MOBIFY_CLIENT_USER }} | ||
| mobify_api_key: ${{ secrets.MOBIFY_CLIENT_API_KEY }} | ||
|
|
||
| - name: Deploy to MRT | ||
| uses: "./.github/actions/push_to_mrt" | ||
| with: | ||
| CWD: "./packages/template-retail-react-app" | ||
| TARGET: extra-features-e2e | ||
| PROJECT: scaffold-pwa | ||
| MESSAGE: "Auto-sync from develop - build ${{ github.run_id }} (${{ github.sha }})" | ||
| FLAGS: --wait |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| /* | ||
| * Copyright (c) 2025, Salesforce, Inc. | ||
| * All rights reserved. | ||
| * SPDX-License-Identifier: BSD-3-Clause | ||
| * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause | ||
| */ | ||
|
|
||
| const {test, expect} = require('@playwright/test') | ||
| const config = require('../../config') | ||
| const {generateUserCredentials} = require('../../scripts/utils.js') | ||
| const {answerConsentTrackingForm} = require('../../scripts/pageHelpers.js') | ||
|
|
||
| const GUEST_USER_CREDENTIALS = generateUserCredentials() | ||
| /** | ||
| * Test that a user can login with passwordless login on mobile. There is no programmatic way to check the email, | ||
| * so we will check that the necessary API call is being made and expected UI is shown | ||
| */ | ||
| test('Verify passwordless login request', async ({page}) => { | ||
| let interceptedRequest = null | ||
|
|
||
| await page.route('**/mobify/slas/private/shopper/auth/v1/organizations/*/oauth2/passwordless/login', (route) => { | ||
| interceptedRequest = route.request() | ||
| route.continue() | ||
| }) | ||
|
|
||
| await page.goto(config.EXTRA_FEATURES_E2E_RETAIL_APP_HOME + '/login') | ||
| await answerConsentTrackingForm(page) | ||
|
|
||
| await page.locator('#email').scrollIntoViewIfNeeded() | ||
| await page.fill('#email', config.PWA_E2E_USER_EMAIL) | ||
|
|
||
| await page.getByRole('button', {name: 'Continue Securely'}).click() | ||
|
|
||
| await page.waitForResponse('**/mobify/slas/private/shopper/auth/v1/organizations/*/oauth2/passwordless/login') | ||
|
|
||
| expect(interceptedRequest).toBeTruthy() | ||
| expect(interceptedRequest.method()).toBe('POST') | ||
|
|
||
| const postData = interceptedRequest.postData() | ||
| expect(postData).toBeTruthy() | ||
|
|
||
| const params = new URLSearchParams(postData) | ||
|
|
||
| expect(params.get('user_id')).toBe(config.PWA_E2E_USER_EMAIL) | ||
| expect(params.get('mode')).toBe('callback') | ||
| expect(params.get('channel_id')).toBe('RefArchGlobal') | ||
| expect(params.get('callback_uri')).toMatch(/.*\/passwordless-login-callback$/) | ||
| }) | ||
|
|
||
| test('Verify password reset callback request', async ({page}) => { | ||
| let interceptedRequest = null | ||
|
|
||
| await page.route('**/mobify/slas/private/shopper/auth/v1/organizations/*/oauth2/password/reset', (route) => { | ||
| interceptedRequest = route.request() | ||
| route.continue() | ||
| }) | ||
|
|
||
| await page.goto(config.EXTRA_FEATURES_E2E_RETAIL_APP_HOME + '/login') | ||
| await answerConsentTrackingForm(page) | ||
|
|
||
| await page.locator('#email').scrollIntoViewIfNeeded() | ||
| await page.fill('#email', config.PWA_E2E_USER_EMAIL) | ||
|
|
||
| await page.getByRole('button', {name: 'Password'}).click() | ||
| await page.getByRole('button', {name: 'Forgot password?'}).click() | ||
|
|
||
| await page.fill('#email', config.PWA_E2E_USER_EMAIL) | ||
| await page.getByRole('button', {name: 'Reset Password'}).click() | ||
|
|
||
| await page.waitForResponse('**/mobify/slas/private/shopper/auth/v1/organizations/*/oauth2/password/reset') | ||
|
|
||
| expect(interceptedRequest).toBeTruthy() | ||
| expect(interceptedRequest.method()).toBe('POST') | ||
|
|
||
| const postData = interceptedRequest.postData() | ||
| expect(postData).toBeTruthy() | ||
|
|
||
| const params = new URLSearchParams(postData) | ||
|
|
||
| expect(params.get('user_id')).toBe(config.PWA_E2E_USER_EMAIL) | ||
| expect(params.get('mode')).toBe('callback') | ||
| expect(params.get('channel_id')).toBe('RefArchGlobal') | ||
| expect(params.get('callback_uri')).toMatch(/.*\/reset-password-callback$/) | ||
| expect(params.get('hint')).toBe('cross_device') | ||
| }) | ||
|
|
||
| test('Verify password reset request', async ({page}) => { | ||
| let interceptedRequest = null | ||
| await page.route('**/mobify/slas/private/shopper/auth/v1/organizations/*/oauth2/password/action', (route) => { | ||
| interceptedRequest = route.request() | ||
| route.continue() | ||
| }) | ||
|
|
||
| await page.goto(config.EXTRA_FEATURES_E2E_RETAIL_APP_HOME + `/reset-password-landing?token=1234567&email=${GUEST_USER_CREDENTIALS.email}`) | ||
| await answerConsentTrackingForm(page) | ||
|
|
||
| await page.fill('#password', GUEST_USER_CREDENTIALS.password) | ||
| await page.fill('#confirmPassword', GUEST_USER_CREDENTIALS.password) | ||
|
|
||
| expect(await page.inputValue('#password')).toBe(GUEST_USER_CREDENTIALS.password) | ||
| expect(await page.inputValue('#confirmPassword')).toBe(GUEST_USER_CREDENTIALS.password) | ||
| await page.getByRole('button', {name: 'Reset Password'}).click() | ||
|
|
||
| await page.waitForResponse('**/mobify/slas/private/shopper/auth/v1/organizations/*/oauth2/password/action') | ||
|
|
||
| expect(interceptedRequest).toBeTruthy() | ||
| }) | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move the siteID to config as well. Incase we need to move the site we're pointing to.