169 lines
No EOL
6.4 KiB
TypeScript
169 lines
No EOL
6.4 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
|
|
// Shared login function
|
|
async function loginAndNavigateToNotes(page, baseURL) {
|
|
const appUrl = baseURL ?? process.env.APP_URL ?? 'http://localhost:8080';
|
|
|
|
// Go directly to login page first
|
|
await page.goto(appUrl + '/login');
|
|
|
|
// Fill credentials and login
|
|
const email = process.env.E2E_EMAIL || 'test@tududi.com';
|
|
const password = process.env.E2E_PASSWORD || 'password123';
|
|
|
|
await page.getByLabel('Email').fill(email);
|
|
await page.getByLabel('Password').fill(password);
|
|
await page.getByRole('button', { name: /login/i }).click();
|
|
|
|
// Wait for redirect to Today view
|
|
await expect(page).toHaveURL(/\/today$/);
|
|
|
|
// Navigate to notes page
|
|
await page.goto(appUrl + '/notes');
|
|
await expect(page).toHaveURL(/\/notes/);
|
|
|
|
return appUrl;
|
|
}
|
|
|
|
// Shared function to create a note via the sidebar button
|
|
async function createNote(page, noteTitle, noteContent = '') {
|
|
// Find the "Add Note" button in the sidebar
|
|
const addNoteButton = page.locator('[data-testid="add-note-button"]');
|
|
await expect(addNoteButton).toBeVisible();
|
|
|
|
// Click the Add Note button
|
|
await addNoteButton.click();
|
|
|
|
// Wait for the Note Modal to appear
|
|
await expect(page.locator('[data-testid="note-title-input"]')).toBeVisible({ timeout: 10000 });
|
|
|
|
// Fill in the note title - focus first, clear, then type
|
|
const titleInput = page.locator('[data-testid="note-title-input"]');
|
|
await titleInput.click();
|
|
await titleInput.clear();
|
|
await titleInput.type(noteTitle, { delay: 50 });
|
|
|
|
// Fill in the note content if provided
|
|
if (noteContent) {
|
|
const contentTextarea = page.locator('[data-testid="note-content-textarea"]');
|
|
await contentTextarea.click();
|
|
await contentTextarea.fill(noteContent);
|
|
}
|
|
|
|
// Save the note using the specific test ID
|
|
await page.locator('[data-testid="note-save-button"]').click();
|
|
|
|
// Wait for the modal to close - wait for it to become not visible
|
|
await expect(page.locator('[data-testid="note-title-input"]')).not.toBeVisible({ timeout: 10000 });
|
|
|
|
// Wait for note creation to complete
|
|
await page.waitForTimeout(2000);
|
|
}
|
|
|
|
test('user can create a new note and verify it appears in the notes list', async ({ page, baseURL }) => {
|
|
await loginAndNavigateToNotes(page, baseURL);
|
|
|
|
// Create a unique test note
|
|
const timestamp = Date.now();
|
|
const noteTitle = `Test Note ${timestamp}`;
|
|
const noteContent = `This is test content for note ${timestamp}`;
|
|
await createNote(page, noteTitle, noteContent);
|
|
|
|
// Verify the note appears in the notes list
|
|
await expect(page.getByText(noteTitle)).toBeVisible({ timeout: 10000 });
|
|
});
|
|
|
|
test('user can update an existing note', async ({ page, baseURL }) => {
|
|
await loginAndNavigateToNotes(page, baseURL);
|
|
|
|
// Create an initial note
|
|
const timestamp = Date.now();
|
|
const originalNoteTitle = `Test note to edit ${timestamp}`;
|
|
const originalNoteContent = `Original content ${timestamp}`;
|
|
await createNote(page, originalNoteTitle, originalNoteContent);
|
|
|
|
// Find the specific note card by title text
|
|
const noteCard = page.locator('a').filter({ hasText: originalNoteTitle });
|
|
await expect(noteCard).toBeVisible();
|
|
|
|
// Hover over the note card to show the dropdown button
|
|
await noteCard.hover();
|
|
|
|
// Wait a moment for any transitions
|
|
await page.waitForTimeout(1000);
|
|
|
|
// Find the dropdown button within this specific note card's parent container
|
|
const dropdownButton = noteCard.locator('..').locator('button[data-testid^="note-dropdown-"]');
|
|
await dropdownButton.click({ force: true });
|
|
|
|
// Wait for dropdown menu to appear and click Edit
|
|
const editButton = page.locator('button[data-testid^="note-edit-"]').first();
|
|
await expect(editButton).toBeVisible({ timeout: 10000 });
|
|
await editButton.click();
|
|
|
|
// Wait for the Note Modal to appear with the note data
|
|
await expect(page.locator('[data-testid="note-title-input"]')).toBeVisible();
|
|
|
|
// Verify the note title field is pre-filled
|
|
const noteTitleInput = page.locator('[data-testid="note-title-input"]');
|
|
await expect(noteTitleInput).toHaveValue(originalNoteTitle);
|
|
|
|
// Edit the note title and content
|
|
const editedNoteTitle = `Edited test note ${timestamp}`;
|
|
const editedNoteContent = `Edited content ${timestamp}`;
|
|
await noteTitleInput.clear();
|
|
await noteTitleInput.fill(editedNoteTitle);
|
|
|
|
const noteContentTextarea = page.locator('[data-testid="note-content-textarea"]');
|
|
await noteContentTextarea.clear();
|
|
await noteContentTextarea.fill(editedNoteContent);
|
|
|
|
// Save the changes
|
|
await page.locator('[data-testid="note-save-button"]').click();
|
|
|
|
// Wait for the modal to close
|
|
await expect(page.locator('[data-testid="note-title-input"]')).not.toBeVisible();
|
|
|
|
// Verify the edited note appears in the notes list
|
|
await expect(page.getByText(editedNoteTitle)).toBeVisible();
|
|
|
|
// Verify the original note title is no longer visible
|
|
await expect(page.getByText(originalNoteTitle)).not.toBeVisible();
|
|
});
|
|
|
|
test('user can delete an existing note', async ({ page, baseURL }) => {
|
|
await loginAndNavigateToNotes(page, baseURL);
|
|
|
|
// Create an initial note
|
|
const timestamp = Date.now();
|
|
const noteTitle = `Test note to delete ${timestamp}`;
|
|
const noteContent = `Content to delete ${timestamp}`;
|
|
await createNote(page, noteTitle, noteContent);
|
|
|
|
// Find the specific note card by title text
|
|
const noteCard = page.locator('a').filter({ hasText: noteTitle });
|
|
await expect(noteCard).toBeVisible();
|
|
|
|
// Hover over the note card to show the dropdown button
|
|
await noteCard.hover();
|
|
|
|
// Wait a moment for any transitions
|
|
await page.waitForTimeout(1000);
|
|
|
|
// Find the dropdown button within this specific note card's parent container
|
|
const dropdownButton = noteCard.locator('..').locator('button[data-testid^="note-dropdown-"]');
|
|
await dropdownButton.click({ force: true });
|
|
|
|
// Wait for dropdown menu to appear and click Delete
|
|
const deleteButton = page.locator('button[data-testid^="note-delete-"]').first();
|
|
await expect(deleteButton).toBeVisible({ timeout: 10000 });
|
|
await deleteButton.click();
|
|
|
|
// Wait for and handle the confirmation dialog
|
|
await expect(page.locator('text=Delete Note')).toBeVisible();
|
|
// Click the red "Delete" button in the confirmation dialog
|
|
await page.locator('[data-testid="confirm-dialog-confirm"]').click();
|
|
|
|
// Verify the note is no longer visible in the notes list (use specific role selector)
|
|
await expect(page.getByRole('link', { name: new RegExp(noteTitle) })).not.toBeVisible();
|
|
}); |