-
Notifications
You must be signed in to change notification settings - Fork 0
Feature/renew style #21
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,6 @@ pnpm-lock.yaml | |
| yarn.lock | ||
| bun.lock | ||
| bun.lockb | ||
|
|
||
| node_modules/ | ||
| # Miscellaneous | ||
| /static/ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,17 +1,19 @@ | ||
| { | ||
| "useTabs": true, | ||
| "semi": false, | ||
| "tabWidth": 2, | ||
| "singleQuote": true, | ||
| "trailingComma": "none", | ||
| "printWidth": 100, | ||
| "plugins": ["prettier-plugin-svelte"], | ||
| "overrides": [ | ||
| { | ||
| "files": "*.svelte", | ||
| "options": { | ||
| "parser": "svelte" | ||
| } | ||
| } | ||
| ] | ||
| "useTabs": false, | ||
| "tabWidth": 2, | ||
| "semi": false, | ||
| "singleQuote": true, | ||
| "trailingComma": "none", | ||
| "printWidth": 100, | ||
| "bracketSameLine": true, | ||
| "bracketSpacing": true, | ||
| "plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"], | ||
| "overrides": [ | ||
| { | ||
| "files": "*.svelte", | ||
| "options": { | ||
| "parser": "svelte" | ||
| } | ||
| } | ||
| ] | ||
| } |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| import { test, expect } from '@playwright/test' | ||
|
|
||
| test.describe('Login Flow', () => { | ||
| test.beforeEach(async ({ page }) => { | ||
| // Replace with your actual login route | ||
| await page.goto('/login') | ||
| }) | ||
|
|
||
| test('should display the login form correctly', async ({ page }) => { | ||
| await expect(page.locator('h1')).toHaveText('Welcome Back') | ||
| await expect(page.locator('label[for="login-email"]')).toBeVisible() | ||
| await expect(page.locator('label[for="login-pw"]')).toBeVisible() | ||
| }) | ||
|
|
||
| test('successful login without MFA redirects to home', async ({ page }) => { | ||
| // Intercept the API call to mock a successful login (no MFA) | ||
| await page.route('**/login', async (route) => { | ||
| // Ensure this matches your PUBLIC_AUTH_URL path | ||
| await route.fulfill({ | ||
| status: 200, | ||
| contentType: 'application/json', | ||
| body: JSON.stringify({ | ||
| token: 'mock-session-token', | ||
| email: 'test@company.com', | ||
| id: '123', | ||
| name: 'Test User', | ||
| info: { phone: '', deviceId: '', googleAuth: '' } | ||
| }) | ||
| }) | ||
| }) | ||
|
|
||
| await page.fill('#login-email', 'test@company.com') | ||
| await page.fill('#login-pw', 'password123') | ||
| await page.click('button[type="submit"]') | ||
|
|
||
| // Verify redirection and session storage | ||
| const token = await page.evaluate(() => sessionStorage.getItem('token')) | ||
| expect(token).toBe('mock-session-token') | ||
| await expect(page).toHaveURL('/') | ||
| }) | ||
|
|
||
| test('login with MFA triggers the MFA Selection view', async ({ page }) => { | ||
| // Mock a response that returns an MFA hash and strategy list | ||
| await page.route('**/login', async (route) => { | ||
| await route.fulfill({ | ||
| status: 200, | ||
| contentType: 'application/json', | ||
| body: JSON.stringify({ | ||
| hash: 'mfa-challenge-123', | ||
| strategyList: ['email', 'totp'] | ||
| }) | ||
| }) | ||
| }) | ||
|
|
||
| await page.fill('#login-email', 'mfa-user@company.com') | ||
| await page.fill('#login-pw', 'password123') | ||
| await page.click('button[type="submit"]') | ||
|
|
||
| // Verify that the 'Default' component is hidden and 'Choose' is shown | ||
| // Note: We check for elements that would exist in choose.svelte | ||
| await expect(page.locator('form')).not.toContainText('Welcome Back') | ||
| }) | ||
|
Comment on lines
+42
to
+62
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Inspect Strategy type and choose.svelte text/testids to confirm a stronger positive assertion.
fd -t f 'mfa.ts' --exec cat {}
fd -t f 'choose.svelte' --exec cat {}Repository: auth-plus/auth-plus-client Length of output: 3796 Fix mock Two issues:
🤖 Prompt for AI Agents |
||
|
|
||
| test('should display error message on failed login', async ({ page }) => { | ||
| // Mock a 401 Unauthorized error | ||
| await page.route('**/login', async (route) => { | ||
| await route.fulfill({ | ||
| status: 401, | ||
| contentType: 'application/json', | ||
| body: JSON.stringify({ message: 'Invalid credentials' }) | ||
| }) | ||
| }) | ||
|
|
||
| await page.fill('#login-email', 'wrong@company.com') | ||
| await page.fill('#login-pw', 'wrongpassword') | ||
| await page.click('button[type="submit"]') | ||
|
|
||
| const errorMsg = page.locator('.text-red-800') | ||
| await expect(errorMsg).toBeVisible() | ||
| await expect(errorMsg).toContainText("Login didn't work") | ||
| }) | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| }) | ||
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.
Race: read
sessionStorageafter asserting navigation, not before.page.click('button[type="submit"]')resolves once the click is dispatched, not aftersubmit()finishes itsawait credential.login(...)andgoto(...). ReadingsessionStorageimmediately after the click can race with the async submit handler and may readnullon a slow run. Wait for the URL change first, then read storage.♻️ Proposed fix
📝 Committable suggestion
🤖 Prompt for AI Agents