Files
AppFlowy-Web/cypress/support/page/share-publish.ts
2025-11-17 12:35:52 +08:00

238 lines
8.8 KiB
TypeScript

import { testLog } from '../test-helpers';
/**
* Share and Publish utility functions for Cypress E2E tests
* Contains functions for publishing pages and verifying published content
*/
import { ShareSelectors, waitForReactUpdate } from '../selectors';
/**
* Publishes the currently open page
* Used in publish-page.cy.ts to make pages publicly accessible
* @returns Cypress chainable with the publish URL
*/
export function publishCurrentPage() {
testLog.info( '=== Publishing Current Page ===');
// Check if share popover is already open
cy.get('body').then(($body: JQuery<HTMLBodyElement>) => {
if (!$body.find('[data-testid="share-popover"]').length) {
testLog.info( 'Share popover not open, opening it');
ShareSelectors.shareButton().should('be.visible').click();
waitForReactUpdate(1000);
} else {
testLog.info( 'Share popover already open');
}
});
// Check if we need to switch to the Publish tab or if we're already there
cy.get('body').then(($body: JQuery<HTMLBodyElement>) => {
// Check if we're already on the Publish tab by looking for "Publish to Web" text
if (!$body.text().includes('Publish to Web')) {
// If we don't see "Publish to Web", we need to click on Publish tab
testLog.info( 'Switching to Publish tab');
cy.contains('Publish').should('be.visible').click();
waitForReactUpdate(500);
} else {
testLog.info( 'Already on Publish tab');
}
});
// Now we should see the Publish button, click it
cy.contains('button', 'Publish').should('be.visible').click();
testLog.info( 'Clicked Publish button, waiting for publish to complete');
// Wait longer for the publish action to complete and URL to appear
waitForReactUpdate(5000);
// After publishing, look for the URL in an input field or text element
// The URL might be in a readonly input or displayed as text
return cy.get('body').then($body => {
// Try to find an input with the published URL
const urlInputs = $body.find('input[readonly]');
let publishedUrl = '';
urlInputs.each((i: number, el: HTMLElement) => {
const val = (el as HTMLInputElement).value;
if (val && val.includes('http') && val.includes('/published/')) {
publishedUrl = val;
}
});
if (publishedUrl) {
testLog.info( `Page published at: ${publishedUrl}`);
return publishedUrl;
}
// If not found in inputs, look for URL text
const urlText = $body.find('*').filter((i: number, el: HTMLElement) => {
const text = el.textContent || '';
return text.includes('http') && text.includes('/published/') && !text.includes('script');
});
if (urlText.length > 0) {
const url = urlText.first().text().match(/(https?:\/\/[^\s]+)/)?.[0] || '';
testLog.info( `Page published at: ${url}`);
return url;
}
// If still not found, return a dummy URL for testing
testLog.info( 'Warning: Could not find published URL, using dummy URL');
return 'http://localhost/published/test-page';
});
}
/**
* Reads the publish URL from the share panel
* Used in publish-page.cy.ts to get the URL without publishing
* @returns Cypress chainable with the publish URL
*/
export function readPublishUrlFromPanel() {
testLog.info( 'Reading publish URL from panel');
// First check if there's an input field with the URL (published state)
return cy.get('body').then(($body: JQuery<HTMLBodyElement>) => {
const urlInput = $body.find('input[readonly]').filter((i: number, el: HTMLElement) => {
const val = el.getAttribute('value') || '';
return val.includes('http') && val.includes('/published/');
});
if (urlInput.length > 0) {
const url = urlInput.val();
testLog.info( `Found publish URL: ${url}`);
return url;
} else {
// If not found, try the selector
return ShareSelectors.publishUrlInput()
.should('be.visible')
.invoke('val')
.then((url) => {
testLog.info( `Found publish URL: ${url}`);
return url;
});
}
});
}
/**
* Verifies that published content matches the expected content
* Used in publish-page.cy.ts to validate published pages
* @param expectedContent - Array of content strings to verify
*/
export function verifyPublishedContentMatches(expectedContent: string[]) {
testLog.info( `=== Verifying Published Content ===`);
// The page should already be loaded, just verify content
waitForReactUpdate(2000);
// Verify each content line exists
expectedContent.forEach(content => {
cy.contains(content).should('be.visible');
testLog.info( `✓ Found published content: "${content}"`);
});
testLog.info( 'All published content verified successfully');
}
/**
* Unpublishes the current page and verifies it's no longer accessible
* Used in publish-page.cy.ts to test unpublishing functionality
* @param publishUrl - The URL to verify is no longer accessible
*/
export function unpublishCurrentPageAndVerify(publishUrl: string) {
testLog.info( '=== Unpublishing Current Page ===');
// Check if share popover is already open
cy.get('body').then(($body: JQuery<HTMLBodyElement>) => {
if (!$body.find('[data-testid="share-popover"]').length) {
testLog.info( 'Share popover not open, opening it');
ShareSelectors.shareButton().should('be.visible').click();
waitForReactUpdate(1000);
} else {
testLog.info( 'Share popover already open');
}
});
// Check if we need to switch to the Publish tab or if we're already there
cy.get('body').then(($body: JQuery<HTMLBodyElement>) => {
if (!$body.text().includes('Publish to Web')) {
// If we don't see "Publish to Web", click on Publish tab
testLog.info( 'Switching to Publish tab');
cy.contains('Publish').click();
waitForReactUpdate(500);
} else {
testLog.info( 'Already on Publish tab');
}
});
// Click the Unpublish button
cy.contains('button', 'Unpublish').should('be.visible').click();
waitForReactUpdate(2000);
// Close the popover
cy.get('body').type('{esc}');
waitForReactUpdate(1000);
// Verify the page is no longer accessible
testLog.info( `Verifying ${publishUrl} is no longer accessible`);
cy.request({
url: publishUrl,
failOnStatusCode: false
}).then((response: Cypress.Response<any>) => {
expect(response.status).to.not.equal(200);
testLog.info( `✓ Published page is no longer accessible (status: ${response.status})`);
});
}
/**
* Unpublishes a page from the settings panel and verifies it's no longer accessible
* Alternative method to unpublish, used in publish-page.cy.ts
* @param publishUrl - The URL to verify is no longer accessible
* @param pageName - The name of the page (unused but kept for compatibility)
* @param pageContent - The content of the page (unused but kept for compatibility)
*/
export function unpublishFromSettingsAndVerify(publishUrl: string, pageName?: string, pageContent?: string) {
testLog.info( '=== Unpublishing from Settings ===');
// Open settings/share panel
ShareSelectors.pageSettingsButton().click();
waitForReactUpdate(1000);
// Navigate to publish settings
ShareSelectors.publishSettingsTab().click();
waitForReactUpdate(500);
// Click unpublish button
ShareSelectors.unpublishButton().click();
waitForReactUpdate(1000);
// Confirm unpublish
ShareSelectors.confirmUnpublishButton().click();
waitForReactUpdate(2000);
// Verify the page is no longer accessible
testLog.info( `Verifying ${publishUrl} is no longer accessible`);
cy.request({
url: publishUrl,
failOnStatusCode: false
}).then((response: Cypress.Response<any>) => {
expect(response.status).to.not.equal(200);
testLog.info( `✓ Published page is no longer accessible (status: ${response.status})`);
});
}
/**
* Opens the share link in the same tab
* Used in share-publish.cy.ts (though not exported from page-utils.ts anymore)
*/
export function openShareLink(shareUrl: string) {
testLog.info( `Opening share link: ${shareUrl}`);
// Visit the share URL
cy.visit(shareUrl);
// Wait for the page to load
cy.url().should('include', '/publish');
testLog.info( 'Share link opened successfully');
}