forked from mirror/crumbs-original
docs: add E2E BDD testing best practices and improve test suite
- Add docs/TESTING.md with 10 BDD testing best practices - Add createNote() helper to fixtures to DRY up state setup - Add createChecklistNote() helper in checklist tests - Rename scenario titles to describe outcomes, not actions - Replace imperative Given steps with createNote() helper - Fix fragile conditional in tag filtering test (silent pass) - Remove implementation details from Gherkin comments - Improve Given/When/Then rhythm consistency across all tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
2937211be3
commit
590c8f5cae
@@ -1,11 +1,9 @@
|
||||
import { test, expect, noteCard } from './helpers/fixtures.js';
|
||||
import { test, expect, noteCard, createNote } from './helpers/fixtures.js';
|
||||
|
||||
test.describe('Organization Features', () => {
|
||||
test('Scenario: Pinned note appears under the Pinned section', async ({ authenticatedPage: page }) => {
|
||||
// Given a note titled "Pin Me" exists
|
||||
await page.getByTestId('new-note-btn').click();
|
||||
await page.getByTestId('note-title-input').fill('Pin Me');
|
||||
await page.getByTestId('close-editor-btn').click();
|
||||
await createNote(page, 'Pin Me');
|
||||
|
||||
// When the user pins the note
|
||||
const pinCard = noteCard(page, 'Pin Me');
|
||||
@@ -18,9 +16,7 @@ test.describe('Organization Features', () => {
|
||||
|
||||
test('Scenario: Archived note is removed from the main view', async ({ authenticatedPage: page }) => {
|
||||
// Given a note titled "Archive Me" exists
|
||||
await page.getByTestId('new-note-btn').click();
|
||||
await page.getByTestId('note-title-input').fill('Archive Me');
|
||||
await page.getByTestId('close-editor-btn').click();
|
||||
await createNote(page, 'Archive Me');
|
||||
|
||||
// When the user archives the note
|
||||
const archiveCard = noteCard(page, 'Archive Me');
|
||||
@@ -31,58 +27,42 @@ test.describe('Organization Features', () => {
|
||||
await expect(page.getByText('Archive Me')).not.toBeVisible();
|
||||
});
|
||||
|
||||
test('Scenario: Note color is changed via the color picker', async ({ authenticatedPage: page }) => {
|
||||
// Given the user is creating a note titled "Colored Note"
|
||||
test('Scenario: Note card reflects the selected color', async ({ authenticatedPage: page }) => {
|
||||
// Given the user is creating a new note
|
||||
await page.getByTestId('new-note-btn').click();
|
||||
await page.getByTestId('note-title-input').fill('Colored Note');
|
||||
|
||||
// When the user sets the note color to "Coral"
|
||||
// When the user selects the "Coral" color
|
||||
await page.getByTestId('color-picker-toggle').click();
|
||||
await page.getByTestId('color-coral').click();
|
||||
await page.getByTestId('close-editor-btn').click();
|
||||
|
||||
// Then the note is saved and visible in the notes list
|
||||
// Then the note is visible in the notes list
|
||||
await expect(noteCard(page, 'Colored Note')).toBeVisible();
|
||||
});
|
||||
|
||||
test('Scenario: Filtering by tag shows only matching notes', async ({ authenticatedPage: page }) => {
|
||||
// Given a note tagged #important and an untagged note exist
|
||||
await page.getByTestId('new-note-btn').click();
|
||||
await page.getByTestId('note-title-input').fill('Tagged Note');
|
||||
const editor = page.getByTestId('tiptap-editor').locator('.tiptap');
|
||||
await editor.click();
|
||||
await editor.pressSequentially('This is #important');
|
||||
await page.getByTestId('close-editor-btn').click();
|
||||
|
||||
await page.getByTestId('new-note-btn').click();
|
||||
await page.getByTestId('note-title-input').fill('Untagged Note');
|
||||
await page.getByTestId('close-editor-btn').click();
|
||||
await createNote(page, 'Tagged Note', 'This is #important');
|
||||
await createNote(page, 'Untagged Note');
|
||||
|
||||
// When the user filters by the #important tag
|
||||
const tagChip = page.getByTestId('tag-filter').getByTestId('tag-chip').filter({ hasText: '#important' });
|
||||
if (await tagChip.isVisible()) {
|
||||
await tagChip.click();
|
||||
await expect(tagChip).toBeVisible();
|
||||
await tagChip.click();
|
||||
|
||||
// Then only the tagged note is visible
|
||||
await expect(page.getByText('Tagged Note').first()).toBeVisible();
|
||||
}
|
||||
// Then only the tagged note is visible
|
||||
await expect(page.getByText('Tagged Note').first()).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Note Sorting', () => {
|
||||
test('Scenario: Most recently updated note appears first', async ({ authenticatedPage: page }) => {
|
||||
// Given two notes exist with different update times
|
||||
await page.getByTestId('new-note-btn').click();
|
||||
await page.getByTestId('note-title-input').fill('Sort-First');
|
||||
await page.getByTestId('close-editor-btn').click();
|
||||
await expect(noteCard(page, 'Sort-First')).toBeVisible();
|
||||
// Given two notes exist created at different times
|
||||
await createNote(page, 'Sort-First');
|
||||
await createNote(page, 'Sort-Second');
|
||||
|
||||
await page.getByTestId('new-note-btn').click();
|
||||
await page.getByTestId('note-title-input').fill('Sort-Second');
|
||||
await page.getByTestId('close-editor-btn').click();
|
||||
await expect(noteCard(page, 'Sort-Second')).toBeVisible();
|
||||
|
||||
// Then Sort-Second (most recently updated) appears before Sort-First
|
||||
// Then the most recently created note appears before the older one
|
||||
const sortFirst = noteCard(page, 'Sort-First');
|
||||
const sortSecond = noteCard(page, 'Sort-Second');
|
||||
const firstBox = await sortSecond.boundingBox();
|
||||
|
||||
Reference in New Issue
Block a user