mirror of
https://github.com/AppFlowy-IO/AppFlowy-Web.git
synced 2025-11-29 10:47:56 +08:00
test: set viewport
This commit is contained in:
@@ -19,6 +19,9 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
e2e: {
|
e2e: {
|
||||||
baseUrl: process.env.CYPRESS_BASE_URL || 'http://localhost:3000',
|
baseUrl: process.env.CYPRESS_BASE_URL || 'http://localhost:3000',
|
||||||
|
// Set viewport to MacBook Pro screen size
|
||||||
|
viewportWidth: 1440,
|
||||||
|
viewportHeight: 900,
|
||||||
setupNodeEvents(on, config) {
|
setupNodeEvents(on, config) {
|
||||||
// Override baseUrl if CYPRESS_BASE_URL is set
|
// Override baseUrl if CYPRESS_BASE_URL is set
|
||||||
if (process.env.CYPRESS_BASE_URL) {
|
if (process.env.CYPRESS_BASE_URL) {
|
||||||
|
|||||||
@@ -1,137 +0,0 @@
|
|||||||
import { v4 as uuidv4 } from 'uuid';
|
|
||||||
import { AuthTestUtils } from '../../support/auth-utils';
|
|
||||||
|
|
||||||
describe('Login Feature Tests with Authentication', () => {
|
|
||||||
const AF_BASE_URL = Cypress.env('AF_BASE_URL');
|
|
||||||
const AF_GOTRUE_URL = Cypress.env('AF_GOTRUE_URL');
|
|
||||||
const generateRandomEmail = () => `${uuidv4()}@appflowy.io`;
|
|
||||||
|
|
||||||
before(() => {
|
|
||||||
// Log environment configuration for debugging
|
|
||||||
cy.task('log', `Test Environment Configuration:
|
|
||||||
- AF_BASE_URL: ${AF_BASE_URL}
|
|
||||||
- AF_GOTRUE_URL: ${AF_GOTRUE_URL}
|
|
||||||
- Running in CI: ${Cypress.env('CI')}
|
|
||||||
- Use Real Backend: ${Cypress.env('USE_REAL_BACKEND')}`);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('LoginAuth Component Tests', () => {
|
|
||||||
it('should generate and exchange tokens for authentication', () => {
|
|
||||||
const randomEmail = generateRandomEmail();
|
|
||||||
const authUtils = new AuthTestUtils();
|
|
||||||
|
|
||||||
cy.task('log', `Testing token generation and exchange for: ${randomEmail}`);
|
|
||||||
|
|
||||||
// Generate sign-in URL and verify token exchange
|
|
||||||
authUtils.generateSignInUrl(randomEmail).then((signInUrl) => {
|
|
||||||
expect(signInUrl).to.include('#access_token=');
|
|
||||||
expect(signInUrl).to.include('refresh_token=');
|
|
||||||
|
|
||||||
cy.task('log', `Generated sign-in URL with tokens for ${randomEmail}`);
|
|
||||||
|
|
||||||
// Extract tokens from the URL
|
|
||||||
const fragment = signInUrl.split('#')[1];
|
|
||||||
const params = new URLSearchParams(fragment);
|
|
||||||
const refreshToken = params.get('refresh_token');
|
|
||||||
const accessToken = params.get('access_token');
|
|
||||||
|
|
||||||
expect(refreshToken).to.exist;
|
|
||||||
expect(accessToken).to.exist;
|
|
||||||
|
|
||||||
// Test the refresh token exchange
|
|
||||||
cy.request({
|
|
||||||
method: 'POST',
|
|
||||||
url: `${AF_GOTRUE_URL}/token?grant_type=refresh_token`,
|
|
||||||
body: {
|
|
||||||
refresh_token: refreshToken,
|
|
||||||
},
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
}).then((response) => {
|
|
||||||
expect(response.status).to.equal(200);
|
|
||||||
expect(response.body.access_token).to.exist;
|
|
||||||
expect(response.body.refresh_token).to.exist;
|
|
||||||
expect(response.body.user).to.exist;
|
|
||||||
|
|
||||||
cy.task('log', `Successfully exchanged refresh token for user: ${response.body.user.email}`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should show AppFlowy Web login page and authenticate', () => {
|
|
||||||
// Handle uncaught exceptions during workspace creation
|
|
||||||
cy.on('uncaught:exception', (err, runnable) => {
|
|
||||||
// Ignore "No workspace or service found" error which happens before workspace is created
|
|
||||||
if (err.message.includes('No workspace or service found')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Let other errors fail the test
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Visit the AppFlowy Web login page
|
|
||||||
cy.visit('/login', { failOnStatusCode: false });
|
|
||||||
|
|
||||||
// Wait for the page to load
|
|
||||||
cy.wait(2000);
|
|
||||||
|
|
||||||
// Check if we're on the login page or if login UI is visible
|
|
||||||
cy.url().then((url) => {
|
|
||||||
cy.task('log', `Current URL: ${url}`);
|
|
||||||
|
|
||||||
// Look for common login elements
|
|
||||||
// This might include login buttons, email inputs, etc.
|
|
||||||
cy.get('body').then(($body) => {
|
|
||||||
// Log what we see on the page
|
|
||||||
cy.task('log', `Page title: ${$body.find('title').text() || document.title}`);
|
|
||||||
|
|
||||||
// Try to find login-related elements
|
|
||||||
const hasLoginButton = $body.find('button:contains("Login"), button:contains("Sign in"), button:contains("Sign In")').length > 0;
|
|
||||||
const hasEmailInput = $body.find('input[type="email"], input[name="email"]').length > 0 ||
|
|
||||||
$body.find('input').filter(function () {
|
|
||||||
return $(this).attr('placeholder')?.toLowerCase().includes('email');
|
|
||||||
}).length > 0;
|
|
||||||
|
|
||||||
if (hasLoginButton || hasEmailInput) {
|
|
||||||
cy.task('log', 'Login page elements found');
|
|
||||||
} else {
|
|
||||||
cy.task('log', 'No obvious login elements found - checking for other auth indicators');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Now test the authentication flow using signInWithTestUrl
|
|
||||||
const randomEmail = generateRandomEmail();
|
|
||||||
const authUtils = new AuthTestUtils();
|
|
||||||
|
|
||||||
cy.task('log', `Testing authentication for: ${randomEmail}`);
|
|
||||||
|
|
||||||
// Use the signInWithTestUrl method which handles the complete flow
|
|
||||||
authUtils.signInWithTestUrl(randomEmail).then(() => {
|
|
||||||
// Verify authentication was successful
|
|
||||||
cy.window().then((win) => {
|
|
||||||
const token = win.localStorage.getItem('token');
|
|
||||||
expect(token).to.exist;
|
|
||||||
|
|
||||||
const tokenData = JSON.parse(token!);
|
|
||||||
expect(tokenData.access_token).to.exist;
|
|
||||||
expect(tokenData.refresh_token).to.exist;
|
|
||||||
expect(tokenData.user).to.exist;
|
|
||||||
|
|
||||||
cy.task('log', `Successfully authenticated user: ${tokenData.user.email}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Verify we're on the app page
|
|
||||||
cy.url().should('include', '/app');
|
|
||||||
|
|
||||||
cy.task('log', 'Authentication flow completed successfully');
|
|
||||||
});
|
|
||||||
cy.wait(2000);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -156,7 +156,7 @@ export class AuthTestUtils {
|
|||||||
if (hashIndex === -1) {
|
if (hashIndex === -1) {
|
||||||
throw new Error('No hash found in callback link');
|
throw new Error('No hash found in callback link');
|
||||||
}
|
}
|
||||||
|
|
||||||
const hash = callbackLink.substring(hashIndex);
|
const hash = callbackLink.substring(hashIndex);
|
||||||
const params = new URLSearchParams(hash.slice(1));
|
const params = new URLSearchParams(hash.slice(1));
|
||||||
const accessToken = params.get('access_token');
|
const accessToken = params.get('access_token');
|
||||||
@@ -173,7 +173,7 @@ export class AuthTestUtils {
|
|||||||
failOnStatusCode: false,
|
failOnStatusCode: false,
|
||||||
}).then((verifyResponse) => {
|
}).then((verifyResponse) => {
|
||||||
cy.task('log', `Token verification response: ${JSON.stringify(verifyResponse)}`);
|
cy.task('log', `Token verification response: ${JSON.stringify(verifyResponse)}`);
|
||||||
|
|
||||||
if (verifyResponse.status !== 200) {
|
if (verifyResponse.status !== 200) {
|
||||||
throw new Error('Token verification failed');
|
throw new Error('Token verification failed');
|
||||||
}
|
}
|
||||||
@@ -196,20 +196,13 @@ export class AuthTestUtils {
|
|||||||
|
|
||||||
// Store the token in localStorage
|
// Store the token in localStorage
|
||||||
const tokenData = response.body;
|
const tokenData = response.body;
|
||||||
|
|
||||||
return cy.window().then((win) => {
|
return cy.window().then((win) => {
|
||||||
win.localStorage.setItem('token', JSON.stringify(tokenData));
|
win.localStorage.setItem('token', JSON.stringify(tokenData));
|
||||||
|
|
||||||
// Now visit the app - we should be authenticated
|
|
||||||
cy.visit('/app');
|
cy.visit('/app');
|
||||||
|
|
||||||
// Wait for the app to load and workspace to be created
|
// Wait for the app to initialize
|
||||||
cy.wait(2000);
|
|
||||||
|
|
||||||
// Reload the page to ensure workspace is loaded after verification
|
|
||||||
cy.reload();
|
|
||||||
|
|
||||||
// Wait for the page to load after reload
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
|
|
||||||
// Verify we're logged in and on the app page
|
// Verify we're logged in and on the app page
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
"test:components:coverage": "cross-env COVERAGE=true cypress run --component --browser chrome --headless",
|
"test:components:coverage": "cross-env COVERAGE=true cypress run --component --browser chrome --headless",
|
||||||
"test:cy": "cypress run",
|
"test:cy": "cypress run",
|
||||||
"test:integration": "cypress run --spec 'cypress/e2e/**/*.cy.ts'",
|
"test:integration": "cypress run --spec 'cypress/e2e/**/*.cy.ts'",
|
||||||
"test:integration:login": "CYPRESS_BASE_URL=http://localhost:3000 node scripts/wait-for-frontend.js && CYPRESS_BASE_URL=http://localhost:3000 cypress run --spec 'cypress/e2e/login/**/*.cy.ts' --headed --browser chrome",
|
"test:integration:user": "cypress run --spec 'cypress/e2e/user/**/*.cy.ts' --headed --browser chrome",
|
||||||
"test:integration:publish": "cypress run --spec 'cypress/e2e/publish/**/*.cy.ts'",
|
"test:integration:publish": "cypress run --spec 'cypress/e2e/publish/**/*.cy.ts'",
|
||||||
"wait:backend": "AF_BASE_URL=${AF_BASE_URL:-http://localhost} node scripts/wait-for-backend.js",
|
"wait:backend": "AF_BASE_URL=${AF_BASE_URL:-http://localhost} node scripts/wait-for-backend.js",
|
||||||
"coverage": "cross-env COVERAGE=true pnpm run test:unit && cross-env COVERAGE=true pnpm run test:components",
|
"coverage": "cross-env COVERAGE=true pnpm run test:unit && cross-env COVERAGE=true pnpm run test:components",
|
||||||
|
|||||||
Reference in New Issue
Block a user