mirror of
https://github.com/AppFlowy-IO/AppFlowy-Web.git
synced 2026-03-13 10:00:26 +08:00
chore: selector
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { avatarTestUtils } from './avatar-test-utils';
|
||||
import { byTestId } from '../../../support/selectors';
|
||||
import { AccountSelectors, AvatarUiSelectors } from '../../../support/selectors';
|
||||
import { testLog } from '../../../support/test-helpers';
|
||||
|
||||
const { generateRandomEmail, setupBeforeEach, imports } = avatarTestUtils;
|
||||
@@ -39,7 +39,7 @@ describe('Avatar API', () => {
|
||||
testLog.info( 'Step 5: Open Account Settings to verify avatar');
|
||||
WorkspaceSelectors.dropdownTrigger().click();
|
||||
cy.wait(1000);
|
||||
cy.get(byTestId('account-settings-button')).click();
|
||||
AccountSelectors.settingsButton().click();
|
||||
AvatarSelectors.accountSettingsDialog().should('be.visible');
|
||||
|
||||
testLog.info( 'Step 6: Verify avatar image is displayed in Account Settings');
|
||||
@@ -50,7 +50,7 @@ describe('Avatar API', () => {
|
||||
|
||||
// Wait for any avatar image to be present and loaded
|
||||
// The AvatarImage component loads asynchronously and sets opacity to 0 while loading
|
||||
cy.get(byTestId('avatar-image'), { timeout: 10000 })
|
||||
AvatarUiSelectors.image()
|
||||
.should('exist')
|
||||
.should(($imgs) => {
|
||||
// Find the first visible avatar image (opacity not 0)
|
||||
@@ -68,7 +68,7 @@ describe('Avatar API', () => {
|
||||
});
|
||||
|
||||
// Verify that the avatar image has loaded (check for non-empty src and visible state)
|
||||
cy.get(byTestId('avatar-image')).then(($imgs) => {
|
||||
AvatarUiSelectors.image().then(($imgs) => {
|
||||
let foundLoaded = false;
|
||||
$imgs.each((index, img) => {
|
||||
const $img = Cypress.$(img);
|
||||
@@ -160,7 +160,7 @@ describe('Avatar API', () => {
|
||||
testLog.info( 'Step 5: Open Account Settings');
|
||||
WorkspaceSelectors.dropdownTrigger().click();
|
||||
cy.wait(1000);
|
||||
cy.get(byTestId('account-settings-button')).click();
|
||||
AccountSelectors.settingsButton().click();
|
||||
AvatarSelectors.accountSettingsDialog().should('be.visible');
|
||||
|
||||
testLog.info( 'Step 6: Verify emoji is displayed in fallback');
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { avatarTestUtils } from './avatar-test-utils';
|
||||
import { byTestIdContains } from '../../../support/selectors';
|
||||
import { PageSelectors } from '../../../support/selectors';
|
||||
import { testLog } from '../../../support/test-helpers';
|
||||
|
||||
const { generateRandomEmail, setupBeforeEach, imports } = avatarTestUtils;
|
||||
@@ -39,12 +39,15 @@ describe('Avatar Header Display', () => {
|
||||
|
||||
testLog.info( 'Step 4: Interact with editor to trigger collaborative user awareness');
|
||||
// Click on a page to open editor
|
||||
cy.get('body').then(($body) => {
|
||||
// Try to find and click on a page in the sidebar
|
||||
if ($body.find(byTestIdContains('page')).length > 0) {
|
||||
cy.get(byTestIdContains('page')).first().click();
|
||||
} else if ($body.text().includes('Getting started')) {
|
||||
cy.contains('Getting started').click();
|
||||
PageSelectors.items().then($pages => {
|
||||
if ($pages.length > 0) {
|
||||
cy.wrap($pages.first()).click();
|
||||
} else {
|
||||
cy.get('body').then($body => {
|
||||
if ($body.text().includes('Getting started')) {
|
||||
cy.contains('Getting started').click();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -118,11 +121,15 @@ describe('Avatar Header Display', () => {
|
||||
|
||||
testLog.info( 'Step 4: Interact with editor to trigger collaborative user awareness');
|
||||
// Click on a page to open editor
|
||||
cy.get('body').then(($body) => {
|
||||
if ($body.find(byTestIdContains('page')).length > 0) {
|
||||
cy.get(byTestIdContains('page')).first().click();
|
||||
} else if ($body.text().includes('Getting started')) {
|
||||
cy.contains('Getting started').click();
|
||||
PageSelectors.items().then($pages => {
|
||||
if ($pages.length > 0) {
|
||||
cy.wrap($pages.first()).click();
|
||||
} else {
|
||||
cy.get('body').then($body => {
|
||||
if ($body.text().includes('Getting started')) {
|
||||
cy.contains('Getting started').click();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -214,11 +221,15 @@ describe('Avatar Header Display', () => {
|
||||
|
||||
testLog.info( 'Step 6: Interact with editor to trigger collaborative user awareness');
|
||||
// Click on a page to open editor
|
||||
cy.get('body').then(($body) => {
|
||||
if ($body.find(byTestIdContains('page')).length > 0) {
|
||||
cy.get(byTestIdContains('page')).first().click();
|
||||
} else if ($body.text().includes('Getting started')) {
|
||||
cy.contains('Getting started').click();
|
||||
PageSelectors.items().then($pages => {
|
||||
if ($pages.length > 0) {
|
||||
cy.wrap($pages.first()).click();
|
||||
} else {
|
||||
cy.get('body').then($body => {
|
||||
if ($body.text().includes('Getting started')) {
|
||||
cy.contains('Getting started').click();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { avatarTestUtils } from './avatar-test-utils';
|
||||
import { byTestId } from '../../../support/selectors';
|
||||
import { AccountSelectors } from '../../../support/selectors';
|
||||
import { testLog } from '../../../support/test-helpers';
|
||||
|
||||
const { generateRandomEmail, setupBeforeEach, imports } = avatarTestUtils;
|
||||
@@ -63,7 +63,7 @@ describe('Avatar Notifications', () => {
|
||||
testLog.info( 'Step 7: Open Account Settings to verify avatar');
|
||||
WorkspaceSelectors.dropdownTrigger().click();
|
||||
cy.wait(1000);
|
||||
cy.get(byTestId('account-settings-button')).click();
|
||||
AccountSelectors.settingsButton().click();
|
||||
AvatarSelectors.accountSettingsDialog().should('be.visible');
|
||||
|
||||
testLog.info( 'Step 8: Verify avatar image uses updated URL');
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { avatarTestUtils } from './avatar-test-utils';
|
||||
import { byTestId } from '../../../support/selectors';
|
||||
import { AccountSelectors } from '../../../support/selectors';
|
||||
import { testLog } from '../../../support/test-helpers';
|
||||
|
||||
const { generateRandomEmail, setupBeforeEach, imports } = avatarTestUtils;
|
||||
@@ -41,7 +41,7 @@ describe('Avatar Persistence', () => {
|
||||
testLog.info( 'Step 5: Verify avatar persisted');
|
||||
WorkspaceSelectors.dropdownTrigger().click();
|
||||
cy.wait(1000);
|
||||
cy.get(byTestId('account-settings-button')).click();
|
||||
AccountSelectors.settingsButton().click();
|
||||
AvatarSelectors.accountSettingsDialog().should('be.visible');
|
||||
|
||||
AvatarSelectors.avatarImage().should('exist').and('have.attr', 'src', testAvatarUrl);
|
||||
@@ -52,7 +52,7 @@ describe('Avatar Persistence', () => {
|
||||
|
||||
WorkspaceSelectors.dropdownTrigger().click();
|
||||
cy.wait(1000);
|
||||
cy.get(byTestId('account-settings-button')).click();
|
||||
AccountSelectors.settingsButton().click();
|
||||
AvatarSelectors.accountSettingsDialog().should('be.visible');
|
||||
|
||||
AvatarSelectors.avatarImage().should('exist').and('have.attr', 'src', testAvatarUrl);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { avatarTestUtils } from './avatar-test-utils';
|
||||
import { byTestId } from '../../../support/selectors';
|
||||
import { AccountSelectors } from '../../../support/selectors';
|
||||
import { testLog } from '../../../support/test-helpers';
|
||||
|
||||
const { generateRandomEmail, setupBeforeEach, imports } = avatarTestUtils;
|
||||
@@ -47,7 +47,7 @@ describe('Avatar Priority', () => {
|
||||
testLog.info( 'Step 5: Verify workspace avatar is displayed (priority)');
|
||||
WorkspaceSelectors.dropdownTrigger().click();
|
||||
cy.wait(1000);
|
||||
cy.get(byTestId('account-settings-button')).click();
|
||||
AccountSelectors.settingsButton().click();
|
||||
AvatarSelectors.accountSettingsDialog().should('be.visible');
|
||||
|
||||
// Workspace avatar should be displayed, not user metadata avatar
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { avatarTestUtils } from './avatar-test-utils';
|
||||
import { byTestId } from '../../../support/selectors';
|
||||
import { AccountSelectors } from '../../../support/selectors';
|
||||
import { testLog } from '../../../support/test-helpers';
|
||||
|
||||
const { generateRandomEmail, setupBeforeEach, imports } = avatarTestUtils;
|
||||
@@ -38,7 +38,7 @@ describe('Avatar Types', () => {
|
||||
|
||||
WorkspaceSelectors.dropdownTrigger().click();
|
||||
cy.wait(1000);
|
||||
cy.get(byTestId('account-settings-button')).click();
|
||||
AccountSelectors.settingsButton().click();
|
||||
AvatarSelectors.accountSettingsDialog().should('be.visible');
|
||||
|
||||
AvatarSelectors.avatarImage().should('exist').and('have.attr', 'src', httpsAvatar);
|
||||
@@ -75,7 +75,7 @@ describe('Avatar Types', () => {
|
||||
|
||||
WorkspaceSelectors.dropdownTrigger().click();
|
||||
cy.wait(1000);
|
||||
cy.get(byTestId('account-settings-button')).click();
|
||||
AccountSelectors.settingsButton().click();
|
||||
AvatarSelectors.accountSettingsDialog().should('be.visible');
|
||||
|
||||
// Emoji should be displayed in fallback, not as image
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { AuthTestUtils } from '../../support/auth-utils';
|
||||
import { WorkspaceSelectors, byTestId } from '../../support/selectors';
|
||||
import { WorkspaceSelectors, AccountSelectors } from '../../support/selectors';
|
||||
import { generateRandomEmail } from '../../support/test-config';
|
||||
|
||||
describe('Update User Profile', () => {
|
||||
@@ -40,61 +40,61 @@ describe('Update User Profile', () => {
|
||||
|
||||
// Click on Account Settings
|
||||
cy.log('Step 4: Opening Account Settings');
|
||||
cy.get(byTestId('account-settings-button')).should('be.visible').click();
|
||||
AccountSelectors.settingsButton().should('be.visible').click();
|
||||
|
||||
// Add a wait to ensure the dialog has time to open
|
||||
cy.wait(1000);
|
||||
|
||||
// Wait for Account Settings dialog to open
|
||||
cy.log('Step 5: Verifying Account Settings dialog opened');
|
||||
cy.get(byTestId('account-settings-dialog'), { timeout: 10000 }).should('be.visible');
|
||||
AccountSelectors.settingsDialog().should('be.visible');
|
||||
|
||||
// Check initial date format (should be Month/Day/Year)
|
||||
cy.log('Step 6: Checking initial date format');
|
||||
cy.get(byTestId('date-format-dropdown')).should('be.visible');
|
||||
AccountSelectors.dateFormatDropdown().should('be.visible');
|
||||
|
||||
// Test Date Format change - select Year/Month/Day
|
||||
cy.log('Step 7: Testing Date Format change to Year/Month/Day');
|
||||
cy.get(byTestId('date-format-dropdown')).click();
|
||||
AccountSelectors.dateFormatDropdown().click();
|
||||
cy.wait(500);
|
||||
|
||||
// Select US format (value 1) which is Year/Month/Day
|
||||
cy.get(byTestId('date-format-1')).should('be.visible').click();
|
||||
AccountSelectors.dateFormatOptionYearMonthDay().should('be.visible').click();
|
||||
cy.wait(3000); // Wait for API call to complete
|
||||
|
||||
// Verify the dropdown now shows Year/Month/Day
|
||||
cy.get(byTestId('date-format-dropdown')).should('contain.text', 'Year/Month/Day');
|
||||
AccountSelectors.dateFormatDropdown().should('contain.text', 'Year/Month/Day');
|
||||
|
||||
// Test Time Format change
|
||||
cy.log('Step 8: Testing Time Format change');
|
||||
cy.get(byTestId('time-format-dropdown')).should('be.visible').click();
|
||||
AccountSelectors.timeFormatDropdown().should('be.visible').click();
|
||||
cy.wait(500);
|
||||
|
||||
// Select 24-hour format (value 1)
|
||||
cy.get(byTestId('time-format-1')).should('be.visible').click();
|
||||
AccountSelectors.timeFormatOption24().should('be.visible').click();
|
||||
cy.wait(3000); // Wait for API call to complete
|
||||
|
||||
// Verify the dropdown now shows 24-hour format
|
||||
cy.get(byTestId('time-format-dropdown')).should('contain.text', '24');
|
||||
AccountSelectors.timeFormatDropdown().should('contain.text', '24');
|
||||
|
||||
// Test Start Week On change
|
||||
cy.log('Step 9: Testing Start Week On change');
|
||||
cy.get(byTestId('start-week-on-dropdown')).should('be.visible').click();
|
||||
AccountSelectors.startWeekDropdown().should('be.visible').click();
|
||||
cy.wait(500);
|
||||
|
||||
// Select Monday (value 1)
|
||||
cy.get(byTestId('start-week-1')).should('be.visible').click();
|
||||
AccountSelectors.startWeekMonday().should('be.visible').click();
|
||||
cy.wait(3000); // Wait for API call to complete
|
||||
|
||||
cy.get(byTestId('start-week-on-dropdown')).should('contain.text', 'Monday');
|
||||
AccountSelectors.startWeekDropdown().should('contain.text', 'Monday');
|
||||
|
||||
// The settings should remain selected in the current session
|
||||
cy.log('Step 10: Verifying all settings are showing correctly');
|
||||
|
||||
// Verify all dropdowns still show the selected values
|
||||
cy.get(byTestId('date-format-dropdown')).should('contain.text', 'Year/Month/Day');
|
||||
cy.get(byTestId('time-format-dropdown')).should('contain.text', '24');
|
||||
cy.get(byTestId('start-week-on-dropdown')).should('contain.text', 'Monday');
|
||||
AccountSelectors.dateFormatDropdown().should('contain.text', 'Year/Month/Day');
|
||||
AccountSelectors.timeFormatDropdown().should('contain.text', '24');
|
||||
AccountSelectors.startWeekDropdown().should('contain.text', 'Monday');
|
||||
|
||||
cy.log('Test completed: User profile settings updated successfully');
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { AuthTestUtils } from '../../support/auth-utils';
|
||||
import { TestTool } from '../../support/page-utils';
|
||||
import { AddPageSelectors, ModelSelectorSelectors, PageSelectors, SidebarSelectors, byTestId } from '../../support/selectors';
|
||||
import { AddPageSelectors, ModelSelectorSelectors, PageSelectors, SidebarSelectors, ChatSelectors } from '../../support/selectors';
|
||||
import { generateRandomEmail, logAppFlowyEnvironment } from '../../support/test-config';
|
||||
|
||||
describe('Chat Input Tests', () => {
|
||||
@@ -55,18 +55,18 @@ describe('Chat Input Tests', () => {
|
||||
|
||||
// Test 1: Format toggle
|
||||
cy.log('Testing format toggle');
|
||||
cy.get('body').then($body => {
|
||||
if ($body.find(byTestId('chat-format-group')).length > 0) {
|
||||
cy.get(byTestId('chat-input-format-toggle')).click();
|
||||
cy.get(byTestId('chat-format-group')).should('not.exist');
|
||||
ChatSelectors.formatGroup().then($group => {
|
||||
if ($group.length > 0) {
|
||||
ChatSelectors.formatToggle().click();
|
||||
ChatSelectors.formatGroup().should('not.exist');
|
||||
}
|
||||
});
|
||||
|
||||
cy.get(byTestId('chat-input-format-toggle')).should('be.visible').click();
|
||||
cy.get(byTestId('chat-format-group')).should('exist');
|
||||
cy.get(byTestId('chat-format-group')).find('button').should('have.length.at.least', 4);
|
||||
cy.get(byTestId('chat-input-format-toggle')).click();
|
||||
cy.get(byTestId('chat-format-group')).should('not.exist');
|
||||
ChatSelectors.formatToggle().should('be.visible').click();
|
||||
ChatSelectors.formatGroup().should('exist');
|
||||
ChatSelectors.formatGroup().find('button').should('have.length.at.least', 4);
|
||||
ChatSelectors.formatToggle().click();
|
||||
ChatSelectors.formatGroup().should('not.exist');
|
||||
|
||||
// Test 2: Model selector
|
||||
cy.log('Testing model selector');
|
||||
@@ -76,7 +76,7 @@ describe('Chat Input Tests', () => {
|
||||
|
||||
// Test 3: Browse prompts
|
||||
cy.log('Testing browse prompts');
|
||||
cy.get(byTestId('chat-input-browse-prompts')).click();
|
||||
ChatSelectors.browsePromptsButton().click();
|
||||
cy.get('[role="dialog"]').should('exist');
|
||||
cy.get('[role="dialog"]').contains('Browse prompts').should('be.visible');
|
||||
cy.get('body').type('{esc}');
|
||||
@@ -84,10 +84,10 @@ describe('Chat Input Tests', () => {
|
||||
|
||||
// Test 4: Related views
|
||||
cy.log('Testing related views');
|
||||
cy.get(byTestId('chat-input-related-views')).click();
|
||||
cy.get(byTestId('chat-related-views-popover')).should('be.visible');
|
||||
ChatSelectors.relatedViewsButton().click();
|
||||
ChatSelectors.relatedViewsPopover().should('be.visible');
|
||||
cy.get('body').type('{esc}');
|
||||
cy.get(byTestId('chat-related-views-popover')).should('not.exist');
|
||||
ChatSelectors.relatedViewsPopover().should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -204,8 +204,8 @@ describe('Chat Input Tests', () => {
|
||||
cy.wait(500);
|
||||
|
||||
// Check send button is disabled when empty
|
||||
cy.get(byTestId('chat-input-send')).should('exist');
|
||||
cy.get(byTestId('chat-input-send')).then($button => {
|
||||
ChatSelectors.sendButton().should('exist');
|
||||
ChatSelectors.sendButton().then($button => {
|
||||
// Button might be disabled via attribute or opacity
|
||||
const isDisabled = $button.prop('disabled') || $button.css('opacity') === '0.5';
|
||||
expect(isDisabled).to.be.true;
|
||||
@@ -215,7 +215,7 @@ describe('Chat Input Tests', () => {
|
||||
getTextarea().type('Test message');
|
||||
cy.wait(500);
|
||||
|
||||
cy.get(byTestId('chat-input-send')).then($button => {
|
||||
ChatSelectors.sendButton().then($button => {
|
||||
const isDisabled = $button.prop('disabled') || $button.css('opacity') === '0.5';
|
||||
expect(isDisabled).to.be.false;
|
||||
});
|
||||
@@ -225,7 +225,7 @@ describe('Chat Input Tests', () => {
|
||||
getTextarea().clear().type('Hello world');
|
||||
cy.wait(500);
|
||||
|
||||
cy.get(byTestId('chat-input-send')).click();
|
||||
ChatSelectors.sendButton().click();
|
||||
cy.wait('@submitQuestion', { timeout: 10000 });
|
||||
|
||||
// Wait for textarea to be ready again
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { AuthTestUtils } from '../../support/auth-utils';
|
||||
import { TestTool } from '../../support/page-utils';
|
||||
import { AddPageSelectors, PageSelectors, ModalSelectors, SidebarSelectors, byTestId, waitForReactUpdate } from '../../support/selectors';
|
||||
import { AddPageSelectors, PageSelectors, ModalSelectors, SidebarSelectors, ChatSelectors, waitForReactUpdate } from '../../support/selectors';
|
||||
import { generateRandomEmail, logAppFlowyEnvironment } from '../../support/test-config';
|
||||
import { testLog } from '../../support/test-helpers';
|
||||
|
||||
@@ -125,8 +125,8 @@ describe('AI Chat Creation and Navigation Tests', () => {
|
||||
testLog.info( '✓ Navigated to AI Chat page');
|
||||
|
||||
// Check if the AI Chat container exists (but don't fail if it doesn't load immediately)
|
||||
cy.get('body').then($body => {
|
||||
if ($body.find(byTestId('ai-chat-container')).length > 0) {
|
||||
ChatSelectors.aiChatContainer().then($container => {
|
||||
if ($container.length > 0) {
|
||||
testLog.info( '✓ AI Chat container exists');
|
||||
} else {
|
||||
testLog.info( 'AI Chat container not immediately visible, checking for navigation success...');
|
||||
@@ -139,15 +139,14 @@ describe('AI Chat Creation and Navigation Tests', () => {
|
||||
// Check for AI Chat specific elements (the chat interface)
|
||||
// The AI chat library loads its own components
|
||||
cy.get('body').then($body => {
|
||||
// Check if chat interface elements exist
|
||||
const hasChatElements = $body.find('.ai-chat').length > 0 ||
|
||||
$body.find(byTestId('ai-chat-container')).length > 0;
|
||||
|
||||
if (hasChatElements) {
|
||||
testLog.info( '✓ AI Chat interface loaded');
|
||||
} else {
|
||||
testLog.info( 'Warning: AI Chat elements not immediately visible, but container exists');
|
||||
}
|
||||
ChatSelectors.aiChatContainer().then($container => {
|
||||
const hasChatElements = $body.find('.ai-chat').length > 0 || $container.length > 0;
|
||||
if (hasChatElements) {
|
||||
testLog.info( '✓ AI Chat interface loaded');
|
||||
} else {
|
||||
testLog.info( 'Warning: AI Chat elements not immediately visible, but container exists');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Verify no error messages are displayed
|
||||
|
||||
@@ -2,8 +2,6 @@ import {
|
||||
AddPageSelectors,
|
||||
DatabaseGridSelectors,
|
||||
CheckboxSelectors,
|
||||
byTestId,
|
||||
byTestIdPrefix,
|
||||
waitForReactUpdate
|
||||
} from '../../support/selectors';
|
||||
import { AuthTestUtils } from '../../support/auth-utils';
|
||||
@@ -59,18 +57,18 @@ describe('Checkbox Column Type', () => {
|
||||
cy.log('[STEP 9] Looking for checkbox elements');
|
||||
cy.get('body').then($body => {
|
||||
// Check for checkbox cells with our data-testid
|
||||
const checkboxCells = $body.find(byTestIdPrefix('checkbox-cell-'));
|
||||
if (checkboxCells.length > 0) {
|
||||
cy.log(`[STEP 10] Found ${checkboxCells.length} checkbox cells`);
|
||||
CheckboxSelectors.allCheckboxCells().then($checkboxCells => {
|
||||
if ($checkboxCells.length > 0) {
|
||||
cy.log(`[STEP 10] Found ${$checkboxCells.length} checkbox cells`);
|
||||
|
||||
// Click first checkbox cell
|
||||
CheckboxSelectors.allCheckboxCells().first().click();
|
||||
waitForReactUpdate(500);
|
||||
cy.log('[STEP 11] Clicked checkbox cell');
|
||||
} else {
|
||||
cy.log('[STEP 10] No checkbox cells found, cell interaction test completed');
|
||||
}
|
||||
});
|
||||
// Click first checkbox cell
|
||||
CheckboxSelectors.allCheckboxCells().first().click();
|
||||
waitForReactUpdate(500);
|
||||
cy.log('[STEP 11] Clicked checkbox cell');
|
||||
} else {
|
||||
cy.log('[STEP 10] No checkbox cells found, cell interaction test completed');
|
||||
}
|
||||
});
|
||||
|
||||
cy.log('[STEP 12] Test completed successfully');
|
||||
});
|
||||
|
||||
@@ -5,8 +5,6 @@ import {
|
||||
PropertyMenuSelectors,
|
||||
GridFieldSelectors,
|
||||
FieldType,
|
||||
byTestId,
|
||||
byTestIdPrefix,
|
||||
waitForReactUpdate
|
||||
} from '../../support/selectors';
|
||||
import { AuthTestUtils } from '../../support/auth-utils';
|
||||
@@ -66,28 +64,23 @@ describe('DateTime Column Type', () => {
|
||||
// The new column is created and the property menu should be open automatically
|
||||
// Let's wait for property trigger to be available
|
||||
cy.log('[STEP 8] Waiting for property menu to open');
|
||||
cy.get('body').then($body => {
|
||||
// Check if property type trigger exists
|
||||
if ($body.find(byTestId('property-type-trigger')).length > 0) {
|
||||
PropertyMenuSelectors.propertyTypeTrigger().then($trigger => {
|
||||
if ($trigger.length > 0) {
|
||||
cy.log('[STEP 9] Property type trigger found, changing to DateTime');
|
||||
PropertyMenuSelectors.propertyTypeTrigger().first().click({ force: true });
|
||||
cy.wrap($trigger.first()).click({ force: true });
|
||||
waitForReactUpdate(1000);
|
||||
|
||||
// Select DateTime option
|
||||
cy.log('[STEP 10] Selecting DateTime option');
|
||||
PropertyMenuSelectors.propertyTypeOption(FieldType.DateTime).click({ force: true });
|
||||
waitForReactUpdate(2000);
|
||||
} else {
|
||||
cy.log('[STEP 9] Property type trigger not found, looking for field header');
|
||||
// Try clicking on the new field header first
|
||||
GridFieldSelectors.allFieldHeaders().last().scrollIntoView().click({ force: true });
|
||||
waitForReactUpdate(1000);
|
||||
|
||||
// Now try to find the property type trigger
|
||||
PropertyMenuSelectors.propertyTypeTrigger().first().click({ force: true });
|
||||
waitForReactUpdate(1000);
|
||||
|
||||
// Select DateTime option
|
||||
cy.log('[STEP 10] Selecting DateTime option');
|
||||
PropertyMenuSelectors.propertyTypeOption(FieldType.DateTime).click({ force: true });
|
||||
waitForReactUpdate(2000);
|
||||
@@ -101,21 +94,17 @@ describe('DateTime Column Type', () => {
|
||||
|
||||
// Verify datetime cells exist
|
||||
cy.log('[STEP 12] Checking for datetime cells');
|
||||
cy.get('body').then($body => {
|
||||
const datetimeCells = $body.find(byTestIdPrefix('datetime-cell-'));
|
||||
if (datetimeCells.length > 0) {
|
||||
cy.log(`[STEP 13] Found ${datetimeCells.length} datetime cells`);
|
||||
DateTimeSelectors.allDateTimeCells().then($cells => {
|
||||
if ($cells.length > 0) {
|
||||
cy.log(`[STEP 13] Found ${$cells.length} datetime cells`);
|
||||
|
||||
// Try to interact with the first datetime cell
|
||||
DateTimeSelectors.allDateTimeCells().first().scrollIntoView().click({ force: true });
|
||||
waitForReactUpdate(1000);
|
||||
|
||||
// Check if picker opens
|
||||
cy.get('body').then($body => {
|
||||
if ($body.find(byTestId('datetime-picker-popover')).length > 0) {
|
||||
DateTimeSelectors.dateTimePickerPopover().then($popover => {
|
||||
if ($popover.length > 0) {
|
||||
cy.log('[STEP 14] DateTime picker opened successfully');
|
||||
|
||||
// Enter a date
|
||||
const today = new Date();
|
||||
const dateStr = `${(today.getMonth() + 1).toString().padStart(2, '0')}/${today.getDate().toString().padStart(2, '0')}/${today.getFullYear()}`;
|
||||
|
||||
|
||||
@@ -6,8 +6,6 @@ import {
|
||||
SingleSelectSelectors,
|
||||
PageSelectors,
|
||||
FieldType,
|
||||
byTestId,
|
||||
byTestIdPrefix,
|
||||
waitForReactUpdate
|
||||
} from '../../support/selectors';
|
||||
import { AuthTestUtils } from '../../support/auth-utils';
|
||||
@@ -54,29 +52,24 @@ describe('Single Select Column Type', () => {
|
||||
cy.log('[STEP 4.1] Waiting for inline add button or new page button');
|
||||
|
||||
// Try to find either inline add button or new page button
|
||||
cy.get('body').then($body => {
|
||||
const inlineAddExists = $body.find(byTestId('inline-add-page')).length > 0;
|
||||
const newPageExists = $body.find(byTestId('new-page-button')).length > 0;
|
||||
|
||||
if (inlineAddExists) {
|
||||
cy.log('[STEP 4.2] Using inline add button');
|
||||
return cy.wrap(null).then(() => {
|
||||
AddPageSelectors.inlineAddButton().then($inlineAdd => {
|
||||
const inlineAddExists = $inlineAdd.length > 0;
|
||||
PageSelectors.newPageButton().then($newPage => {
|
||||
const newPageExists = $newPage.length > 0;
|
||||
|
||||
if (inlineAddExists) {
|
||||
cy.log('[STEP 4.2] Using inline add button');
|
||||
AddPageSelectors.inlineAddButton().first().click({ force: true });
|
||||
});
|
||||
} else if (newPageExists) {
|
||||
cy.log('[STEP 4.2] Using new page button instead');
|
||||
return cy.wrap(null).then(() => {
|
||||
} else if (newPageExists) {
|
||||
cy.log('[STEP 4.2] Using new page button instead');
|
||||
PageSelectors.newPageButton().first().click({ force: true });
|
||||
});
|
||||
} else {
|
||||
// Wait a bit more and try inline add button
|
||||
cy.log('[STEP 4.2] Waiting for UI to stabilize');
|
||||
return cy.wrap(null).then(() => {
|
||||
} else {
|
||||
cy.log('[STEP 4.2] Waiting for UI to stabilize');
|
||||
cy.wait(3000);
|
||||
AddPageSelectors.inlineAddButton().should('exist', { timeout: 15000 });
|
||||
AddPageSelectors.inlineAddButton().first().click({ force: true });
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
waitForReactUpdate(1000);
|
||||
@@ -166,14 +159,13 @@ describe('Single Select Column Type', () => {
|
||||
|
||||
// Check if property menu is open and change to SingleSelect
|
||||
cy.log('[STEP 7] Changing column type to SingleSelect');
|
||||
cy.get('body').then($body => {
|
||||
if ($body.find(byTestId('property-type-trigger')).length > 0) {
|
||||
PropertyMenuSelectors.propertyTypeTrigger().first().click({ force: true });
|
||||
PropertyMenuSelectors.propertyTypeTrigger().then($trigger => {
|
||||
if ($trigger.length > 0) {
|
||||
cy.wrap($trigger.first()).click({ force: true });
|
||||
waitForReactUpdate(1000);
|
||||
PropertyMenuSelectors.propertyTypeOption(FieldType.SingleSelect).click({ force: true });
|
||||
waitForReactUpdate(2000);
|
||||
} else {
|
||||
// Try clicking on the field header first
|
||||
GridFieldSelectors.allFieldHeaders().last().scrollIntoView().click({ force: true });
|
||||
waitForReactUpdate(1000);
|
||||
PropertyMenuSelectors.propertyTypeTrigger().first().click({ force: true });
|
||||
@@ -191,20 +183,16 @@ describe('Single Select Column Type', () => {
|
||||
cy.log('[STEP 8] Adding select options to cells');
|
||||
|
||||
// First try to find select cells
|
||||
cy.get('body').then($body => {
|
||||
const selectCells = $body.find(byTestIdPrefix('select-option-cell-'));
|
||||
|
||||
if (selectCells.length > 0) {
|
||||
cy.log(`[STEP 9] Found ${selectCells.length} select cells`);
|
||||
SingleSelectSelectors.allSelectOptionCells().then($cells => {
|
||||
if ($cells.length > 0) {
|
||||
cy.log(`[STEP 9] Found ${$cells.length} select cells`);
|
||||
|
||||
// Click first cell with force and add option
|
||||
SingleSelectSelectors.allSelectOptionCells().first().click({ force: true });
|
||||
waitForReactUpdate(500);
|
||||
cy.focused().type('Option A{enter}');
|
||||
waitForReactUpdate(1000);
|
||||
|
||||
// Add second option if possible
|
||||
if (selectCells.length > 1) {
|
||||
if ($cells.length > 1) {
|
||||
SingleSelectSelectors.allSelectOptionCells().eq(1).click({ force: true });
|
||||
waitForReactUpdate(500);
|
||||
cy.focused().type('Option B{enter}');
|
||||
@@ -213,18 +201,14 @@ describe('Single Select Column Type', () => {
|
||||
} else {
|
||||
cy.log('[STEP 9] No select cells found, using regular cells');
|
||||
|
||||
// Get all rows and find cells in the newly added column
|
||||
DatabaseGridSelectors.rows().first().within(() => {
|
||||
// Click the last cell in this row (should be the new column)
|
||||
DatabaseGridSelectors.cells().last().click({ force: true });
|
||||
waitForReactUpdate(500);
|
||||
});
|
||||
|
||||
// Type option A
|
||||
cy.focused().type('Option A{enter}');
|
||||
waitForReactUpdate(1000);
|
||||
|
||||
// Try second row
|
||||
DatabaseGridSelectors.rows().eq(1).within(() => {
|
||||
DatabaseGridSelectors.cells().last().click({ force: true });
|
||||
waitForReactUpdate(500);
|
||||
@@ -241,9 +225,9 @@ describe('Single Select Column Type', () => {
|
||||
waitForReactUpdate(1000);
|
||||
|
||||
// Click edit property if available
|
||||
cy.get('body').then($body => {
|
||||
if ($body.find(byTestId('grid-field-edit-property')).length > 0) {
|
||||
PropertyMenuSelectors.editPropertyMenuItem().click();
|
||||
PropertyMenuSelectors.editPropertyMenuItem().then($edit => {
|
||||
if ($edit.length > 0) {
|
||||
cy.wrap($edit).click();
|
||||
waitForReactUpdate(1000);
|
||||
}
|
||||
});
|
||||
@@ -285,9 +269,9 @@ describe('Single Select Column Type', () => {
|
||||
waitForReactUpdate(1000);
|
||||
|
||||
// Click edit property if available
|
||||
cy.get('body').then($body => {
|
||||
if ($body.find(byTestId('grid-field-edit-property')).length > 0) {
|
||||
PropertyMenuSelectors.editPropertyMenuItem().click();
|
||||
PropertyMenuSelectors.editPropertyMenuItem().then($edit => {
|
||||
if ($edit.length > 0) {
|
||||
cy.wrap($edit).click();
|
||||
waitForReactUpdate(1000);
|
||||
}
|
||||
});
|
||||
@@ -305,18 +289,15 @@ describe('Single Select Column Type', () => {
|
||||
|
||||
// Verify select options are displayed again
|
||||
cy.log('[STEP 16] Verifying select options are displayed again');
|
||||
cy.get('body').then($body => {
|
||||
const selectCells = $body.find(byTestIdPrefix('select-option-cell-'));
|
||||
if (selectCells.length > 0) {
|
||||
cy.log(`[STEP 17] Success! Found ${selectCells.length} select option cells after conversion`);
|
||||
SingleSelectSelectors.allSelectOptionCells().then($cells => {
|
||||
if ($cells.length > 0) {
|
||||
cy.log(`[STEP 17] Success! Found ${$cells.length} select option cells after conversion`);
|
||||
|
||||
// Click on a cell to verify options are still available
|
||||
SingleSelectSelectors.allSelectOptionCells().first().click();
|
||||
waitForReactUpdate(500);
|
||||
|
||||
// Check if select menu appears
|
||||
cy.get('body').then($body => {
|
||||
if ($body.find(byTestId('select-option-menu')).length > 0) {
|
||||
SingleSelectSelectors.selectOptionMenu().then($menu => {
|
||||
if ($menu.length > 0) {
|
||||
cy.log('[STEP 18] Select option menu opened - options preserved!');
|
||||
} else {
|
||||
cy.log('[STEP 18] Select cells exist but menu behavior may differ');
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { AuthTestUtils } from '../../support/auth-utils';
|
||||
import { TestTool } from '../../support/page-utils';
|
||||
import {
|
||||
import { testLog } from '../../support/test-helpers';
|
||||
import {
|
||||
PageSelectors,
|
||||
SpaceSelectors,
|
||||
SidebarSelectors,
|
||||
byTestId,
|
||||
byTestIdContains,
|
||||
BreadcrumbSelectors,
|
||||
waitForReactUpdate
|
||||
} from '../../support/selectors';
|
||||
import { generateRandomEmail, logAppFlowyEnvironment } from '../../support/test-config';
|
||||
@@ -73,12 +72,10 @@ describe('Breadcrumb Navigation Complete Tests', () => {
|
||||
|
||||
// Step 4: Check for breadcrumb navigation
|
||||
testLog.info( '=== Step 4: Checking for breadcrumb navigation ===');
|
||||
cy.get('body').then($body => {
|
||||
if ($body.find(byTestId('breadcrumb-navigation')).length > 0) {
|
||||
BreadcrumbSelectors.navigation().then($nav => {
|
||||
if ($nav.length > 0) {
|
||||
testLog.info( '✓ Breadcrumb navigation found on this page');
|
||||
|
||||
// Count breadcrumb items
|
||||
cy.get(byTestIdContains('breadcrumb-item-')).then($items => {
|
||||
BreadcrumbSelectors.items().then($items => {
|
||||
testLog.info( `✓ Found ${$items.length} breadcrumb items`);
|
||||
});
|
||||
} else {
|
||||
@@ -135,19 +132,19 @@ describe('Breadcrumb Navigation Complete Tests', () => {
|
||||
|
||||
// Check for breadcrumb navigation
|
||||
testLog.info( '=== Step 4: Testing breadcrumb navigation ===');
|
||||
cy.get('body', { timeout: 5000 }).then($body => {
|
||||
if ($body.find(byTestId('breadcrumb-navigation')).length > 0) {
|
||||
BreadcrumbSelectors.navigation().then($nav => {
|
||||
if ($nav.length > 0) {
|
||||
testLog.info( '✓ Breadcrumb navigation is visible');
|
||||
|
||||
// Try to click breadcrumb to navigate back
|
||||
if ($body.find(byTestIdContains('breadcrumb-item-')).length > 1) {
|
||||
cy.get(byTestIdContains('breadcrumb-item-')).first().click({ force: true });
|
||||
testLog.info( '✓ Clicked breadcrumb item to navigate back');
|
||||
cy.wait(2000);
|
||||
testLog.info( '✓ Successfully used breadcrumb navigation');
|
||||
} else {
|
||||
testLog.info( 'Only one breadcrumb item found');
|
||||
}
|
||||
BreadcrumbSelectors.items().then($items => {
|
||||
if ($items.length > 1) {
|
||||
cy.wrap($items).first().click({ force: true });
|
||||
testLog.info( '✓ Clicked breadcrumb item to navigate back');
|
||||
cy.wait(2000);
|
||||
testLog.info( '✓ Successfully used breadcrumb navigation');
|
||||
} else {
|
||||
testLog.info( 'Only one breadcrumb item found');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
testLog.info( 'No breadcrumb navigation on nested page');
|
||||
}
|
||||
@@ -253,22 +250,16 @@ describe('Breadcrumb Navigation Complete Tests', () => {
|
||||
|
||||
// Step 4: Test breadcrumb navigation
|
||||
testLog.info( '=== Step 4: Testing breadcrumb navigation ===');
|
||||
cy.get('body').then($body => {
|
||||
if ($body.find(byTestId('breadcrumb-navigation')).length > 0) {
|
||||
BreadcrumbSelectors.navigation().then($nav => {
|
||||
if ($nav.length > 0) {
|
||||
testLog.info( '✓ Breadcrumb navigation is visible');
|
||||
|
||||
// Check breadcrumb items with timeout
|
||||
cy.get(byTestIdContains('breadcrumb-item-'), { timeout: 10000 }).then($items => {
|
||||
BreadcrumbSelectors.items().then($items => {
|
||||
testLog.info( `Found ${$items.length} breadcrumb items`);
|
||||
|
||||
if ($items.length > 1) {
|
||||
// Click second-to-last breadcrumb (parent page)
|
||||
const targetIndex = Math.max(0, $items.length - 2);
|
||||
cy.wrap($items[targetIndex]).click({ force: true });
|
||||
testLog.info( `✓ Clicked breadcrumb at index ${targetIndex} to go back`);
|
||||
cy.wait(2000);
|
||||
|
||||
// Verify navigation worked
|
||||
testLog.info( '✓ Successfully navigated back using breadcrumb');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { AuthTestUtils } from '../../support/auth-utils';
|
||||
import { TestTool } from '../../support/page-utils';
|
||||
import { PageSelectors, ModalSelectors, SidebarSelectors, byTestId, waitForReactUpdate } from '../../support/selectors';
|
||||
import { PageSelectors, ModalSelectors, SidebarSelectors, TrashSelectors, waitForReactUpdate } from '../../support/selectors';
|
||||
import { generateRandomEmail, logAppFlowyEnvironment } from '../../support/test-config';
|
||||
import { testLog } from '../../support/test-helpers';
|
||||
|
||||
@@ -164,7 +164,7 @@ describe('Delete Page, Verify in Trash, and Restore Tests', () => {
|
||||
testLog.info( '=== Step 5: Navigating to trash page ===');
|
||||
|
||||
// Click on the trash button in the sidebar
|
||||
cy.get(byTestId('sidebar-trash-button')).click();
|
||||
TrashSelectors.sidebarTrashButton().click();
|
||||
|
||||
// Wait for navigation
|
||||
cy.wait(2000);
|
||||
@@ -177,10 +177,10 @@ describe('Delete Page, Verify in Trash, and Restore Tests', () => {
|
||||
testLog.info( '=== Step 6: Verifying deleted page exists in trash ===');
|
||||
|
||||
// Wait for trash table to load
|
||||
cy.get(byTestId('trash-table'), { timeout: 10000 }).should('be.visible');
|
||||
TrashSelectors.table().should('be.visible');
|
||||
|
||||
// Look for our deleted page in the trash table
|
||||
cy.get(byTestId('trash-table-row')).then($rows => {
|
||||
TrashSelectors.rows().then($rows => {
|
||||
let foundPage = false;
|
||||
|
||||
// Check each row for our page name
|
||||
@@ -206,13 +206,13 @@ describe('Delete Page, Verify in Trash, and Restore Tests', () => {
|
||||
// Step 7: Verify restore and permanent delete buttons are present
|
||||
testLog.info( '=== Step 7: Verifying trash actions are available ===');
|
||||
|
||||
cy.get(byTestId('trash-table-row')).first().within(() => {
|
||||
TrashSelectors.rows().first().within(() => {
|
||||
// Check for restore button
|
||||
cy.get(byTestId('trash-restore-button')).should('exist');
|
||||
TrashSelectors.restoreButton().should('exist');
|
||||
testLog.info( '✓ Restore button found');
|
||||
|
||||
// Check for permanent delete button
|
||||
cy.get(byTestId('trash-delete-button')).should('exist');
|
||||
TrashSelectors.deleteButton().should('exist');
|
||||
testLog.info( '✓ Permanent delete button found');
|
||||
});
|
||||
|
||||
@@ -223,7 +223,7 @@ describe('Delete Page, Verify in Trash, and Restore Tests', () => {
|
||||
let restoredPageName = 'Untitled'; // Default to Untitled since that's what usually gets created
|
||||
|
||||
// Click the restore button on the first row (our deleted page)
|
||||
cy.get(byTestId('trash-table-row')).first().within(() => {
|
||||
TrashSelectors.rows().first().within(() => {
|
||||
// Get the page name before restoring
|
||||
cy.get('td').first().invoke('text').then((text) => {
|
||||
restoredPageName = text.trim() || 'Untitled';
|
||||
@@ -231,7 +231,7 @@ describe('Delete Page, Verify in Trash, and Restore Tests', () => {
|
||||
});
|
||||
|
||||
// Click restore button
|
||||
cy.get(byTestId('trash-restore-button')).click();
|
||||
TrashSelectors.restoreButton().click();
|
||||
});
|
||||
|
||||
// Wait for restore to complete
|
||||
@@ -242,30 +242,26 @@ describe('Delete Page, Verify in Trash, and Restore Tests', () => {
|
||||
testLog.info( '=== Step 9: Verifying page is removed from trash ===');
|
||||
|
||||
// Check if trash is now empty or doesn't contain our page
|
||||
cy.get('body').then(($body) => {
|
||||
// Check if there are any rows left in trash
|
||||
const rowsExist = $body.find(byTestId('trash-table-row')).length > 0;
|
||||
TrashSelectors.rows().then($rows => {
|
||||
const rowsExist = $rows.length > 0;
|
||||
|
||||
if (!rowsExist) {
|
||||
testLog.info( '✓ Trash is now empty - page successfully removed from trash');
|
||||
} else {
|
||||
// If there are still rows, verify our page is not among them
|
||||
cy.get(byTestId('trash-table-row')).then($rows => {
|
||||
let pageStillInTrash = false;
|
||||
|
||||
$rows.each((index, row) => {
|
||||
const rowText = Cypress.$(row).text();
|
||||
if (rowText.includes(restoredPageName)) {
|
||||
pageStillInTrash = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (pageStillInTrash) {
|
||||
throw new Error(`Page "${restoredPageName}" is still in trash after restore`);
|
||||
} else {
|
||||
testLog.info( `✓ Page "${restoredPageName}" successfully removed from trash`);
|
||||
let pageStillInTrash = false;
|
||||
|
||||
$rows.each((index, row) => {
|
||||
const rowText = Cypress.$(row).text();
|
||||
if (rowText.includes(restoredPageName)) {
|
||||
pageStillInTrash = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (pageStillInTrash) {
|
||||
throw new Error(`Page "${restoredPageName}" is still in trash after restore`);
|
||||
} else {
|
||||
testLog.info( `✓ Page "${restoredPageName}" successfully removed from trash`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { AuthTestUtils } from '../../support/auth-utils';
|
||||
import { TestTool } from '../../support/page-utils';
|
||||
import { PageSelectors, byTestId, waitForReactUpdate } from '../../support/selectors';
|
||||
import { PageSelectors, ModalSelectors, waitForReactUpdate } from '../../support/selectors';
|
||||
import { generateRandomEmail } from '../../support/test-config';
|
||||
import { testLog } from '../../support/test-helpers';
|
||||
|
||||
@@ -189,15 +189,15 @@ describe('More Page Actions', () => {
|
||||
testLog.info( 'Clicked Rename option');
|
||||
|
||||
// Wait for the rename modal to appear
|
||||
cy.get(byTestId('rename-modal-input'), { timeout: 5000 })
|
||||
.should('be.visible')
|
||||
ModalSelectors.renameInput()
|
||||
.should('be.visible', { timeout: 5000 })
|
||||
.clear()
|
||||
.type(renamedPageName);
|
||||
|
||||
testLog.info( `Entered new page name: ${renamedPageName}`);
|
||||
|
||||
// Click the save button
|
||||
cy.get(byTestId('rename-modal-save')).click();
|
||||
ModalSelectors.renameSaveButton().click();
|
||||
|
||||
testLog.info( 'Clicked save button');
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { AuthTestUtils } from '../../support/auth-utils';
|
||||
import { TestTool } from '../../support/page-utils';
|
||||
import { PageSelectors, ShareSelectors, SidebarSelectors, byTestId } from '../../support/selectors';
|
||||
import { PageSelectors, ShareSelectors, SidebarSelectors } from '../../support/selectors';
|
||||
import { generateRandomEmail, logAppFlowyEnvironment } from '../../support/test-config';
|
||||
import { testLog } from '../../support/test-helpers';
|
||||
|
||||
@@ -71,7 +71,7 @@ describe('Publish Page Test', () => {
|
||||
cy.wait(5000);
|
||||
|
||||
// Verify that the page is now published by checking for published UI elements
|
||||
cy.get(byTestId('publish-namespace')).should('be.visible', { timeout: 10000 });
|
||||
cy.get(ShareSelectors.publishNamespace()).should('be.visible', { timeout: 10000 });
|
||||
testLog.info( 'Page published successfully, URL elements visible');
|
||||
|
||||
// 6. Get the published URL by constructing it from UI elements
|
||||
@@ -79,8 +79,8 @@ describe('Publish Page Test', () => {
|
||||
const origin = win.location.origin;
|
||||
|
||||
// Get namespace and publish name from the UI
|
||||
cy.get(byTestId('publish-namespace')).should('be.visible').invoke('text').then((namespace) => {
|
||||
cy.get(byTestId('publish-name-input')).should('be.visible').invoke('val').then((publishName) => {
|
||||
cy.get(ShareSelectors.publishNamespace()).should('be.visible').invoke('text').then((namespace) => {
|
||||
cy.get(ShareSelectors.publishNameInput()).should('be.visible').invoke('val').then((publishName) => {
|
||||
const namespaceText = namespace.trim();
|
||||
const publishNameText = String(publishName).trim();
|
||||
const publishedUrl = `${origin}/${namespaceText}/${publishNameText}`;
|
||||
@@ -91,7 +91,7 @@ describe('Publish Page Test', () => {
|
||||
// Located in a div with class "p-1 text-text-primary" next to the URL container
|
||||
ShareSelectors.sharePopover().within(() => {
|
||||
// Find the parent container that holds both URL inputs and copy button
|
||||
cy.get(byTestId('publish-name-input'))
|
||||
cy.get(ShareSelectors.publishNameInput())
|
||||
.closest('div.flex.w-full.items-center.overflow-hidden')
|
||||
.find('div.p-1.text-text-primary')
|
||||
.should('be.visible')
|
||||
@@ -263,13 +263,13 @@ describe('Publish Page Test', () => {
|
||||
cy.wait(5000);
|
||||
|
||||
// Verify published
|
||||
cy.get(byTestId('publish-namespace')).should('be.visible', { timeout: 10000 });
|
||||
cy.get(ShareSelectors.publishNamespace()).should('be.visible', { timeout: 10000 });
|
||||
|
||||
// Get the published URL
|
||||
cy.window().then((win) => {
|
||||
const origin = win.location.origin;
|
||||
cy.get(byTestId('publish-namespace')).should('be.visible').invoke('text').then((namespace) => {
|
||||
cy.get(byTestId('publish-name-input')).should('be.visible').invoke('val').then((publishName) => {
|
||||
cy.get(ShareSelectors.publishNamespace()).should('be.visible').invoke('text').then((namespace) => {
|
||||
cy.get(ShareSelectors.publishNameInput()).should('be.visible').invoke('val').then((publishName) => {
|
||||
const publishedUrl = `${origin}/${namespace.trim()}/${String(publishName).trim()}`;
|
||||
testLog.info( `Published URL: ${publishedUrl}`);
|
||||
|
||||
@@ -315,20 +315,20 @@ describe('Publish Page Test', () => {
|
||||
|
||||
ShareSelectors.publishConfirmButton().should('be.visible').click({ force: true });
|
||||
cy.wait(5000);
|
||||
cy.get(byTestId('publish-namespace')).should('be.visible', { timeout: 10000 });
|
||||
cy.get(ShareSelectors.publishNamespace()).should('be.visible', { timeout: 10000 });
|
||||
|
||||
// Get original URL
|
||||
cy.window().then((win) => {
|
||||
const origin = win.location.origin;
|
||||
cy.get(byTestId('publish-namespace')).invoke('text').then((namespace) => {
|
||||
cy.get(byTestId('publish-name-input')).invoke('val').then((originalName) => {
|
||||
cy.get(ShareSelectors.publishNamespace()).invoke('text').then((namespace) => {
|
||||
cy.get(ShareSelectors.publishNameInput()).invoke('val').then((originalName) => {
|
||||
const namespaceText = namespace.trim();
|
||||
const originalNameText = String(originalName).trim();
|
||||
testLog.info( `Original publish name: ${originalNameText}`);
|
||||
|
||||
// Edit the publish name directly in the input
|
||||
const newPublishName = `custom-name-${Date.now()}`;
|
||||
cy.get(byTestId('publish-name-input'))
|
||||
cy.get(ShareSelectors.publishNameInput())
|
||||
.clear()
|
||||
.type(newPublishName)
|
||||
.blur();
|
||||
@@ -397,14 +397,14 @@ describe('Publish Page Test', () => {
|
||||
|
||||
ShareSelectors.publishConfirmButton().should('be.visible').click({ force: true });
|
||||
cy.wait(5000);
|
||||
cy.get(byTestId('publish-namespace')).should('be.visible', { timeout: 10000 });
|
||||
cy.get(ShareSelectors.publishNamespace()).should('be.visible', { timeout: 10000 });
|
||||
testLog.info( '✓ First publish successful');
|
||||
|
||||
// Get published URL
|
||||
cy.window().then((win) => {
|
||||
const origin = win.location.origin;
|
||||
cy.get(byTestId('publish-namespace')).invoke('text').then((namespace) => {
|
||||
cy.get(byTestId('publish-name-input')).invoke('val').then((publishName) => {
|
||||
cy.get(ShareSelectors.publishNamespace()).invoke('text').then((namespace) => {
|
||||
cy.get(ShareSelectors.publishNameInput()).invoke('val').then((publishName) => {
|
||||
const publishedUrl = `${origin}/${namespace.trim()}/${String(publishName).trim()}`;
|
||||
testLog.info( `Published URL: ${publishedUrl}`);
|
||||
|
||||
@@ -458,7 +458,7 @@ describe('Publish Page Test', () => {
|
||||
// Republish with updated content
|
||||
ShareSelectors.publishConfirmButton().should('be.visible').click({ force: true });
|
||||
cy.wait(5000);
|
||||
cy.get(byTestId('publish-namespace')).should('be.visible', { timeout: 10000 });
|
||||
cy.get(ShareSelectors.publishNamespace()).should('be.visible', { timeout: 10000 });
|
||||
testLog.info( '✓ Republished successfully');
|
||||
|
||||
// Verify updated content is published
|
||||
@@ -501,14 +501,14 @@ describe('Publish Page Test', () => {
|
||||
|
||||
ShareSelectors.publishConfirmButton().should('be.visible').click({ force: true });
|
||||
cy.wait(5000);
|
||||
cy.get(byTestId('publish-namespace')).should('be.visible', { timeout: 10000 });
|
||||
cy.get(ShareSelectors.publishNamespace()).should('be.visible', { timeout: 10000 });
|
||||
|
||||
// Try to set invalid publish name with spaces
|
||||
cy.get(byTestId('publish-name-input')).invoke('val').then((originalName) => {
|
||||
cy.get(ShareSelectors.publishNameInput()).invoke('val').then((originalName) => {
|
||||
testLog.info( `Original name: ${originalName}`);
|
||||
|
||||
// Try to set name with space (should be rejected)
|
||||
cy.get(byTestId('publish-name-input'))
|
||||
cy.get(ShareSelectors.publishNameInput())
|
||||
.clear()
|
||||
.type('invalid name with spaces')
|
||||
.blur();
|
||||
@@ -519,7 +519,7 @@ describe('Publish Page Test', () => {
|
||||
cy.get('body').then(($body) => {
|
||||
const bodyText = $body.text();
|
||||
// The name should either revert or show an error
|
||||
cy.get(byTestId('publish-name-input')).invoke('val').then((currentName) => {
|
||||
cy.get(ShareSelectors.publishNameInput()).invoke('val').then((currentName) => {
|
||||
// Name should not contain spaces (validation should prevent it)
|
||||
if (String(currentName).includes(' ')) {
|
||||
testLog.info( '⚠ Warning: Invalid characters were not rejected');
|
||||
@@ -558,7 +558,7 @@ describe('Publish Page Test', () => {
|
||||
|
||||
ShareSelectors.publishConfirmButton().should('be.visible').click({ force: true });
|
||||
cy.wait(5000);
|
||||
cy.get(byTestId('publish-namespace')).should('be.visible', { timeout: 10000 });
|
||||
cy.get(ShareSelectors.publishNamespace()).should('be.visible', { timeout: 10000 });
|
||||
|
||||
// Test comments switch - find by looking for Switch components in the published panel
|
||||
ShareSelectors.sharePopover().within(() => {
|
||||
@@ -632,13 +632,13 @@ describe('Publish Page Test', () => {
|
||||
|
||||
ShareSelectors.publishConfirmButton().should('be.visible').click({ force: true });
|
||||
cy.wait(5000);
|
||||
cy.get(byTestId('publish-namespace')).should('be.visible', { timeout: 10000 });
|
||||
cy.get(ShareSelectors.publishNamespace()).should('be.visible', { timeout: 10000 });
|
||||
|
||||
// Get first URL
|
||||
cy.window().then((win) => {
|
||||
const origin = win.location.origin;
|
||||
cy.get(byTestId('publish-namespace')).invoke('text').then((namespace) => {
|
||||
cy.get(byTestId('publish-name-input')).invoke('val').then((publishName) => {
|
||||
cy.get(ShareSelectors.publishNamespace()).invoke('text').then((namespace) => {
|
||||
cy.get(ShareSelectors.publishNameInput()).invoke('val').then((publishName) => {
|
||||
firstPublishedUrl = `${origin}/${namespace.trim()}/${String(publishName).trim()}`;
|
||||
testLog.info( `First published URL: ${firstPublishedUrl}`);
|
||||
|
||||
@@ -651,9 +651,9 @@ describe('Publish Page Test', () => {
|
||||
cy.contains('Publish').should('exist').click({ force: true });
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get(byTestId('publish-namespace')).should('be.visible', { timeout: 10000 });
|
||||
cy.get(byTestId('publish-namespace')).invoke('text').then((namespace2) => {
|
||||
cy.get(byTestId('publish-name-input')).invoke('val').then((publishName2) => {
|
||||
cy.get(ShareSelectors.publishNamespace()).should('be.visible', { timeout: 10000 });
|
||||
cy.get(ShareSelectors.publishNamespace()).invoke('text').then((namespace2) => {
|
||||
cy.get(ShareSelectors.publishNameInput()).invoke('val').then((publishName2) => {
|
||||
const secondPublishedUrl = `${origin}/${namespace2.trim()}/${String(publishName2).trim()}`;
|
||||
testLog.info( `Second check URL: ${secondPublishedUrl}`);
|
||||
|
||||
@@ -750,7 +750,7 @@ describe('Publish Page Test', () => {
|
||||
cy.wait(5000);
|
||||
|
||||
// Verify that the database is now published by checking for published UI elements
|
||||
cy.get(byTestId('publish-namespace')).should('be.visible', { timeout: 10000 });
|
||||
cy.get(ShareSelectors.publishNamespace()).should('be.visible', { timeout: 10000 });
|
||||
testLog.info( 'Database published successfully, URL elements visible');
|
||||
|
||||
// Get the published URL
|
||||
@@ -758,8 +758,8 @@ describe('Publish Page Test', () => {
|
||||
const origin = win.location.origin;
|
||||
|
||||
// Get namespace and publish name from the UI
|
||||
cy.get(byTestId('publish-namespace')).should('be.visible').invoke('text').then((namespace) => {
|
||||
cy.get(byTestId('publish-name-input')).should('be.visible').invoke('val').then((publishName) => {
|
||||
cy.get(ShareSelectors.publishNamespace()).should('be.visible').invoke('text').then((namespace) => {
|
||||
cy.get(ShareSelectors.publishNameInput()).should('be.visible').invoke('val').then((publishName) => {
|
||||
const namespaceText = namespace.trim();
|
||||
const publishNameText = String(publishName).trim();
|
||||
const publishedUrl = `${origin}/${namespaceText}/${publishNameText}`;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { AuthTestUtils } from '../../support/auth-utils';
|
||||
import { TestTool } from '../../support/page-utils';
|
||||
import { PageSelectors, SpaceSelectors, SidebarSelectors, byTestId, waitForReactUpdate } from '../../support/selectors';
|
||||
import { PageSelectors, SpaceSelectors, SidebarSelectors, ModalSelectors, waitForReactUpdate } from '../../support/selectors';
|
||||
import { generateRandomEmail, logAppFlowyEnvironment } from '../../support/test-config';
|
||||
import { testLog } from '../../support/test-helpers';
|
||||
|
||||
@@ -83,7 +83,7 @@ describe('Space Creation Tests', () => {
|
||||
// Step 3: Click on "Create New Space" option
|
||||
testLog.info( '=== Step 3: Clicking Create New Space option ===');
|
||||
|
||||
cy.get(byTestId('create-new-space-button'))
|
||||
SpaceSelectors.createNewSpaceButton()
|
||||
.should('be.visible')
|
||||
.click();
|
||||
|
||||
@@ -96,13 +96,13 @@ describe('Space Creation Tests', () => {
|
||||
testLog.info( '=== Step 4: Filling space creation form ===');
|
||||
|
||||
// Verify the modal is visible
|
||||
cy.get(byTestId('create-space-modal'))
|
||||
SpaceSelectors.createSpaceModal()
|
||||
.should('be.visible');
|
||||
|
||||
testLog.info( 'Create Space modal is visible');
|
||||
|
||||
// Enter space name
|
||||
cy.get(byTestId('space-name-input'))
|
||||
SpaceSelectors.spaceNameInput()
|
||||
.should('be.visible')
|
||||
.clear()
|
||||
.type(spaceName);
|
||||
@@ -116,7 +116,7 @@ describe('Space Creation Tests', () => {
|
||||
testLog.info( '=== Step 5: Saving new space ===');
|
||||
|
||||
// Click the Save button
|
||||
cy.get(byTestId('modal-ok-button'))
|
||||
ModalSelectors.okButton()
|
||||
.should('be.visible')
|
||||
.click();
|
||||
|
||||
|
||||
@@ -81,6 +81,19 @@ export const SpaceSelectors = {
|
||||
|
||||
// Get more actions button for spaces
|
||||
moreActionsButton: () => cy.get(byTestId('inline-more-actions')),
|
||||
|
||||
// New space creation controls
|
||||
createNewSpaceButton: () => cy.get(byTestId('create-new-space-button')),
|
||||
createSpaceModal: () => cy.get(byTestId('create-space-modal')),
|
||||
spaceNameInput: () => cy.get(byTestId('space-name-input')),
|
||||
};
|
||||
|
||||
/**
|
||||
* Breadcrumb selectors
|
||||
*/
|
||||
export const BreadcrumbSelectors = {
|
||||
navigation: () => cy.get(byTestId('breadcrumb-navigation')),
|
||||
items: () => cy.get(byTestIdContains('breadcrumb-item-')),
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -124,6 +137,13 @@ export const ModalSelectors = {
|
||||
|
||||
// Get space item in modal
|
||||
spaceItemInModal: () => cy.get(byTestId('space-item')),
|
||||
|
||||
// Generic modal accept/ok button
|
||||
okButton: () => cy.get(byTestId('modal-ok-button')),
|
||||
|
||||
// Rename modal inputs
|
||||
renameInput: () => cy.get(byTestId('rename-modal-input')),
|
||||
renameSaveButton: () => cy.get(byTestId('rename-modal-save')),
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -154,6 +174,10 @@ export const ShareSelectors = {
|
||||
// Publish URL input
|
||||
publishUrlInput: () => cy.get(byTestId('publish-url-input')),
|
||||
|
||||
// Publish namespace and name inputs
|
||||
publishNamespace: () => cy.get(byTestId('publish-namespace')),
|
||||
publishNameInput: () => cy.get(byTestId('publish-name-input')),
|
||||
|
||||
// Page settings button
|
||||
pageSettingsButton: () => cy.get(byTestId('page-settings-button')),
|
||||
|
||||
@@ -201,6 +225,17 @@ export const SidebarSelectors = {
|
||||
pageHeader: () => cy.get(byTestId('sidebar-page-header')),
|
||||
};
|
||||
|
||||
/**
|
||||
* Trash view selectors
|
||||
*/
|
||||
export const TrashSelectors = {
|
||||
sidebarTrashButton: () => cy.get(byTestId('sidebar-trash-button')),
|
||||
table: () => cy.get(byTestId('trash-table')),
|
||||
rows: () => cy.get(byTestId('trash-table-row')),
|
||||
restoreButton: () => cy.get(byTestId('trash-restore-button')),
|
||||
deleteButton: () => cy.get(byTestId('trash-delete-button')),
|
||||
};
|
||||
|
||||
/**
|
||||
* Chat Model Selector-related selectors
|
||||
* Used for testing AI model selection in chat interface
|
||||
@@ -222,6 +257,19 @@ export const ModelSelectorSelectors = {
|
||||
selectedOption: () => cy.get('[data-testid^="model-option-"]').filter('.bg-fill-content-select'),
|
||||
};
|
||||
|
||||
/**
|
||||
* Chat UI selectors
|
||||
*/
|
||||
export const ChatSelectors = {
|
||||
aiChatContainer: () => cy.get(byTestId('ai-chat-container')),
|
||||
formatToggle: () => cy.get(byTestId('chat-input-format-toggle')),
|
||||
formatGroup: () => cy.get(byTestId('chat-format-group')),
|
||||
browsePromptsButton: () => cy.get(byTestId('chat-input-browse-prompts')),
|
||||
relatedViewsButton: () => cy.get(byTestId('chat-input-related-views')),
|
||||
relatedViewsPopover: () => cy.get(byTestId('chat-related-views-popover')),
|
||||
sendButton: () => cy.get(byTestId('chat-input-send')),
|
||||
};
|
||||
|
||||
/**
|
||||
* Database Grid-related selectors
|
||||
*/
|
||||
@@ -445,6 +493,27 @@ export const AuthSelectors = {
|
||||
logoutConfirmButton: () => cy.get(byTestId('logout-confirm-button')),
|
||||
};
|
||||
|
||||
/**
|
||||
* Account settings selectors
|
||||
*/
|
||||
export const AccountSelectors = {
|
||||
settingsButton: () => cy.get(byTestId('account-settings-button')),
|
||||
settingsDialog: () => cy.get(byTestId('account-settings-dialog')),
|
||||
dateFormatDropdown: () => cy.get(byTestId('date-format-dropdown')),
|
||||
dateFormatOptionYearMonthDay: () => cy.get(byTestId('date-format-1')),
|
||||
timeFormatDropdown: () => cy.get(byTestId('time-format-dropdown')),
|
||||
timeFormatOption24: () => cy.get(byTestId('time-format-1')),
|
||||
startWeekDropdown: () => cy.get(byTestId('start-week-on-dropdown')),
|
||||
startWeekMonday: () => cy.get(byTestId('start-week-1')),
|
||||
};
|
||||
|
||||
/**
|
||||
* Avatar display selectors
|
||||
*/
|
||||
export const AvatarUiSelectors = {
|
||||
image: () => cy.get(byTestId('avatar-image')),
|
||||
};
|
||||
|
||||
export function waitForReactUpdate(ms: number = 500) {
|
||||
return cy.wait(ms);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user