mirror of
https://github.com/AppFlowy-IO/AppFlowy-Web.git
synced 2025-12-01 03:47:55 +08:00
chore: page more action
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { AuthTestUtils } from '../../support/auth-utils';
|
||||
import { PageUtils } from '../../support/page-utils';
|
||||
import { TestTool } from '../../support/page-utils';
|
||||
|
||||
describe('Page Create and Delete Tests', () => {
|
||||
const AF_BASE_URL = Cypress.env('AF_BASE_URL');
|
||||
@@ -13,9 +13,7 @@ describe('Page Create and Delete Tests', () => {
|
||||
// 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')}`);
|
||||
- AF_GOTRUE_URL: ${AF_GOTRUE_URL}`);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -41,58 +39,57 @@ describe('Page Create and Delete Tests', () => {
|
||||
const authUtils = new AuthTestUtils();
|
||||
authUtils.signInWithTestUrl(testEmail).then(() => {
|
||||
cy.url().should('include', '/app');
|
||||
cy.task('log', 'Authentication completed successfully');
|
||||
cy.wait(3000);
|
||||
|
||||
// Step 2: Create a new page
|
||||
PageUtils.clickNewPageButton();
|
||||
TestTool.clickNewPageButton();
|
||||
cy.task('log', 'Clicked New Page button');
|
||||
|
||||
// Wait for the modal to open
|
||||
cy.wait(1000);
|
||||
|
||||
// Select the first space in the modal
|
||||
PageUtils.selectFirstSpaceInModal();
|
||||
TestTool.selectFirstSpaceInModal();
|
||||
|
||||
// Wait for the page to be created and modal to open
|
||||
cy.wait(2000);
|
||||
|
||||
// Enter the page name
|
||||
cy.task('log', `Entering page title: ${testPageName}`);
|
||||
PageUtils.enterPageTitle(testPageName);
|
||||
TestTool.enterPageTitle(testPageName);
|
||||
|
||||
// Save the title and close the modal
|
||||
PageUtils.savePageTitle();
|
||||
TestTool.savePageTitle();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.task('log', `Created page with title: ${testPageName}`);
|
||||
|
||||
// Step 3: Reload and verify the page exists
|
||||
cy.reload();
|
||||
PageUtils.waitForPageLoad(3000);
|
||||
TestTool.waitForPageLoad(3000);
|
||||
|
||||
// Expand the first space to see its pages
|
||||
PageUtils.expandSpace();
|
||||
TestTool.expandSpace();
|
||||
cy.wait(1000);
|
||||
|
||||
// Verify the page exists
|
||||
PageUtils.verifyPageExists('e2e test-create page');
|
||||
TestTool.verifyPageExists('e2e test-create page');
|
||||
cy.task('log', `Verified page exists after reload: ${testPageName}`);
|
||||
|
||||
// Step 4: Delete the page
|
||||
PageUtils.deletePageByName('e2e test-create page');
|
||||
TestTool.deletePageByName('e2e test-create page');
|
||||
cy.task('log', `Deleted page: ${testPageName}`);
|
||||
|
||||
// Step 5: Reload and verify the page is gone
|
||||
cy.reload();
|
||||
PageUtils.waitForPageLoad(3000);
|
||||
TestTool.waitForPageLoad(3000);
|
||||
|
||||
// Expand the space again to check if page is gone
|
||||
PageUtils.expandSpace();
|
||||
TestTool.expandSpace();
|
||||
cy.wait(1000);
|
||||
|
||||
// Verify the page no longer exists
|
||||
PageUtils.verifyPageNotExists('e2e test-create page');
|
||||
TestTool.verifyPageNotExists('e2e test-create page');
|
||||
cy.task('log', `Verified page is gone after reload: ${testPageName}`);
|
||||
});
|
||||
});
|
||||
|
||||
Binary file not shown.
191
cypress/e2e/page/more-page-action.cy.ts
Normal file
191
cypress/e2e/page/more-page-action.cy.ts
Normal file
@@ -0,0 +1,191 @@
|
||||
import { AuthTestUtils } from 'cypress/support/auth-utils';
|
||||
import { uuidv4 } from 'lib0/random';
|
||||
import { TestTool } from '../../support/page-utils';
|
||||
|
||||
describe('More Page Actions', () => {
|
||||
const AF_BASE_URL = Cypress.env('AF_BASE_URL');
|
||||
const AF_GOTRUE_URL = Cypress.env('AF_GOTRUE_URL');
|
||||
const newPageName = 'Renamed Test Page';
|
||||
let testEmail: string;
|
||||
let testEmail2: string;
|
||||
|
||||
before(function () {
|
||||
testEmail = `${uuidv4()}@appflowy.io`;
|
||||
testEmail2 = `${uuidv4()}@appflowy.io`;
|
||||
cy.session(testEmail, () => {
|
||||
const authUtils = new AuthTestUtils();
|
||||
authUtils.signInWithTestUrl(testEmail);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
it('should open the More actions menu for a page (verify visibility of core items)', () => {
|
||||
cy.visit('/app', { failOnStatusCode: false });
|
||||
// Expand General space if present, otherwise expand first
|
||||
// cy.get('body').then(($body) => {
|
||||
// const hasSpace = $body.find('[data-testid="space-name"]').length > 0;
|
||||
// if (hasSpace) {
|
||||
// TestTool.expandSpace('General');
|
||||
// }
|
||||
// });
|
||||
TestTool.expandSpace('General');
|
||||
cy.task('log', 'Expanded space');
|
||||
|
||||
// // Wait for pages to render
|
||||
// cy.get('[data-testid="page-name"]', { timeout: 20000 }).should('exist');
|
||||
// cy.task('log', 'Pages rendered');
|
||||
|
||||
// Open the first available page from the sidebar, then trigger inline ViewActionsPopover via "..." on the row
|
||||
cy.get('[data-testid="page-name"]', { timeout: 30000 }).should('exist').first().invoke('text').then((raw) => {
|
||||
const pageName = (raw || '').trim();
|
||||
cy.task('log', `Opening ViewActionsPopover for page: ${pageName}`);
|
||||
TestTool.openViewActionsPopoverForPage(pageName);
|
||||
});
|
||||
cy.task('log', 'Opened ViewActionsPopover');
|
||||
|
||||
// Verify core items in ViewActionsPopover
|
||||
// The menu should be open now, verify at least one of the common actions exists
|
||||
cy.get('[data-slot="dropdown-menu-content"]', { timeout: 5000 }).should('exist');
|
||||
|
||||
// Check for common menu items - they might have different test ids or text
|
||||
cy.get('[data-slot="dropdown-menu-content"]').within(() => {
|
||||
// Look for items by text content since test ids might vary
|
||||
cy.contains('Delete').should('exist');
|
||||
cy.contains('Duplicate').should('exist');
|
||||
cy.contains('Move to').should('exist');
|
||||
});
|
||||
});
|
||||
|
||||
it('should trigger Rename flow from More actions (opens rename modal/input)', () => {
|
||||
// Create a new session for this test
|
||||
cy.session(testEmail2, () => {
|
||||
const authUtils = new AuthTestUtils();
|
||||
authUtils.signInWithTestUrl(testEmail2);
|
||||
});
|
||||
|
||||
// Visit the app
|
||||
cy.visit('/app', { failOnStatusCode: false });
|
||||
cy.wait(2000); // Wait for app to load
|
||||
|
||||
// Expand space if needed by clicking on it
|
||||
cy.get('[data-testid="space-name"]').first().parent().parent().click({ force: true });
|
||||
cy.wait(500);
|
||||
|
||||
// Get the first page and open its more actions menu
|
||||
cy.get('[data-testid="page-name"]', { timeout: 30000 }).should('exist').first().invoke('text').then((raw) => {
|
||||
const originalPageName = (raw || '').trim();
|
||||
cy.task('log', `Opening More Actions for page: ${originalPageName}`);
|
||||
|
||||
// Open the more actions menu for this page
|
||||
TestTool.openViewActionsPopoverForPage(originalPageName);
|
||||
|
||||
// Click on Rename option
|
||||
cy.get('[data-slot="dropdown-menu-content"]').within(() => {
|
||||
cy.get('[data-testid="more-page-rename"]').click();
|
||||
});
|
||||
cy.task('log', 'Clicked Rename option');
|
||||
|
||||
// Wait for the rename modal or inline editor to appear
|
||||
cy.wait(1000);
|
||||
|
||||
// Check if a modal opened or if it's inline editing
|
||||
cy.get('body').then(($body) => {
|
||||
const hasModal = $body.find('[role="dialog"]').length > 0;
|
||||
const hasPageTitleInput = $body.find('[data-testid="page-title-input"]').length > 0;
|
||||
|
||||
if (hasPageTitleInput) {
|
||||
// It's a page title input (modal or inline)
|
||||
cy.task('log', 'Found page title input');
|
||||
TestTool.getPageTitleInput()
|
||||
.should('be.visible')
|
||||
.clear()
|
||||
.type('Renamed Test Page');
|
||||
|
||||
// Save by pressing Escape
|
||||
TestTool.savePageTitle();
|
||||
} else if (hasModal) {
|
||||
// Check if there's an input field in the modal
|
||||
cy.task('log', 'Found modal, looking for input');
|
||||
cy.get('[role="dialog"]').within(() => {
|
||||
cy.get('input').first().clear().type('Renamed Test Page');
|
||||
// Look for a save/confirm button or press Enter
|
||||
cy.get('input').first().type('{enter}');
|
||||
});
|
||||
} else {
|
||||
// Maybe it's inline editing in the sidebar
|
||||
cy.task('log', 'Checking for inline editing in sidebar');
|
||||
// The page name itself might become editable
|
||||
cy.get(`[data-testid="page-name"]:contains("${originalPageName}")`).first().then(($el) => {
|
||||
// Try to click and type directly
|
||||
cy.wrap($el).click().clear().type('Renamed Test Page{enter}');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
cy.wait(1000); // Wait for the rename to be saved
|
||||
|
||||
// Verify the page was renamed in the sidebar
|
||||
TestTool.getPageByName('Renamed Test Page').should('be.visible');
|
||||
cy.task('log', 'Page successfully renamed');
|
||||
});
|
||||
});
|
||||
|
||||
// it('should open Change Icon popover from More actions', () => {
|
||||
|
||||
// });
|
||||
|
||||
// it('should remove icon via Change Icon popover', () => {
|
||||
// TestTool.morePageActionsChangeIcon();
|
||||
|
||||
// cy.get('[role="dialog"]').within(() => {
|
||||
// cy.contains('button', 'Remove').click();
|
||||
// });
|
||||
|
||||
// TestTool.getModal().should('not.exist');
|
||||
// cy.get('.view-icon').should('not.exist');
|
||||
// });
|
||||
|
||||
// it('should upload a custom icon via Change Icon popover', () => {
|
||||
// TestTool.morePageActionsChangeIcon();
|
||||
|
||||
// cy.get('[role="dialog"]').within(() => {
|
||||
// cy.get('input[type="file"]').attachFile('test-icon.png');
|
||||
// });
|
||||
|
||||
// TestTool.getModal().should('not.exist');
|
||||
// cy.get('.view-icon').should('exist');
|
||||
// });
|
||||
|
||||
// it('should open page in a new tab from More actions', () => {
|
||||
// cy.window().then((win) => {
|
||||
// cy.stub(win, 'open').as('open');
|
||||
// });
|
||||
|
||||
// TestTool.morePageActionsOpenNewTab();
|
||||
// cy.get('@open').should('be.called');
|
||||
// });
|
||||
|
||||
// it('should duplicate page from More actions and show success toast', () => {
|
||||
// TestTool.morePageActionsDuplicate();
|
||||
// cy.wait(2000);
|
||||
// TestTool.getPageByName('Get started').should('have.length', 2);
|
||||
// });
|
||||
|
||||
// it('should move page to another space from More actions', () => {
|
||||
// TestTool.morePageActionsMoveTo();
|
||||
|
||||
// cy.get('[role="dialog"]').within(() => {
|
||||
// TestTool.getSpaceItems().first().click();
|
||||
// });
|
||||
// cy.wait(2000);
|
||||
// TestTool.getPageByName('Get started').should('be.visible');
|
||||
// });
|
||||
|
||||
// it('should delete page from More actions and confirm deletion', () => {
|
||||
// TestTool.morePageActionsDelete();
|
||||
// TestTool.confirmPageDeletion();
|
||||
// cy.wait(2000);
|
||||
// TestTool.getPageByName('Get started').should('not.exist');
|
||||
// });
|
||||
});
|
||||
90
cypress/e2e/page/publish-page.cy.ts
Normal file
90
cypress/e2e/page/publish-page.cy.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { AuthTestUtils } from '../../support/auth-utils';
|
||||
import { TestTool } from '../../support/page-utils';
|
||||
|
||||
describe('Publish Page Test', () => {
|
||||
const AF_BASE_URL = Cypress.env('AF_BASE_URL');
|
||||
const AF_GOTRUE_URL = Cypress.env('AF_GOTRUE_URL');
|
||||
const generateRandomEmail = () => `${uuidv4()}@appflowy.io`;
|
||||
|
||||
let testEmail: string;
|
||||
const pageName = 'publish page';
|
||||
const pageContent = 'This is a publish page content';
|
||||
|
||||
before(() => {
|
||||
cy.task('log', `Env:\n- AF_BASE_URL: ${AF_BASE_URL}\n- AF_GOTRUE_URL: ${AF_GOTRUE_URL}`);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
testEmail = generateRandomEmail();
|
||||
});
|
||||
|
||||
it('sign in, create a page, type content, open share and publish', () => {
|
||||
// Handle uncaught exceptions during workspace creation
|
||||
cy.on('uncaught:exception', (err) => {
|
||||
if (err.message.includes('No workspace or service found')) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
// 1. sign in
|
||||
cy.visit('/login', { failOnStatusCode: false });
|
||||
cy.wait(1000);
|
||||
const authUtils = new AuthTestUtils();
|
||||
authUtils.signInWithTestUrl(testEmail).then(() => {
|
||||
cy.url().should('include', '/app');
|
||||
cy.task('log', 'Signed in');
|
||||
cy.wait(2000);
|
||||
|
||||
// 2. create a new page called publish page and add content
|
||||
TestTool.createPageAndAddContent(pageName, [pageContent]);
|
||||
cy.task('log', 'Page created and content added');
|
||||
|
||||
// Skip publish functionality in WebSocket mock mode as it requires full backend
|
||||
|
||||
TestTool.openSharePopover();
|
||||
cy.task('log', 'Share popover opened');
|
||||
|
||||
TestTool.publishCurrentPage();
|
||||
cy.task('log', 'Page published');
|
||||
|
||||
// Open the public page (stubbed) and verify content
|
||||
TestTool.verifyPublishedContentMatches([pageContent]);
|
||||
cy.task('log', 'Published content verified');
|
||||
|
||||
// Capture the current public URL
|
||||
cy.location('href').then((href) => {
|
||||
const publishUrl = String(href);
|
||||
cy.task('log', `Captured published URL: ${publishUrl}`);
|
||||
|
||||
// Return to the app source page
|
||||
cy.go('back');
|
||||
cy.task('log', 'Returned to app');
|
||||
|
||||
// Unpublish via panel and verify link is inaccessible
|
||||
TestTool.unpublishCurrentPageAndVerify(publishUrl);
|
||||
cy.task('log', 'Unpublished via panel and verified link is inaccessible');
|
||||
|
||||
// Navigate back to app and reopen the page to re-publish for settings test
|
||||
cy.visit('/app', { failOnStatusCode: false });
|
||||
// Use WebSocket-aware page opening
|
||||
TestTool.openPageFromSidebar(pageName);
|
||||
TestTool.openSharePopover();
|
||||
TestTool.publishCurrentPage();
|
||||
cy.task('log', 'Re-published for settings test');
|
||||
|
||||
// Get the public URL again from share popover
|
||||
TestTool.readPublishUrlFromPanel().then((url2) => {
|
||||
const publishUrl2 = String(url2 || '');
|
||||
cy.task('log', `Captured published URL for settings: ${publishUrl2}`);
|
||||
|
||||
// Unpublish from settings and verify
|
||||
TestTool.unpublishFromSettingsAndVerify(publishUrl2, pageName, pageContent);
|
||||
cy.task('log', 'Unpublished via settings and verified link is inaccessible');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user