mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-07-17 16:37:43 +00:00
test(e2e): fix recurring task tests failing in CI production builds
Replace window.ng.getComponent() calls with UI-based interactions. Angular debug APIs are unavailable in production builds (CI uses ng build which defaults to production config with enableProdMode). - Use calendar picker instead of signal manipulation for date setting - Remove page.evaluate() model verification (input value checks suffice) - Replace waitForTimeout with proper toBeVisible/toBeEnabled waits - Fix date input focus issues with click + pressSequentially - Use en-GB date format (DD/MM/YYYY) matching app default locale
This commit is contained in:
parent
2431b2748a
commit
a578cbfa86
2 changed files with 34 additions and 67 deletions
|
|
@ -28,43 +28,42 @@ test.describe('Recurring Task - Future Start Date (#6856)', () => {
|
|||
|
||||
// 2. Open task detail and click on recur to open the repeat dialog
|
||||
await task.hover();
|
||||
await page.waitForTimeout(200);
|
||||
const detailBtn = page.getByRole('button', {
|
||||
name: 'Show/Hide additional info',
|
||||
});
|
||||
await expect(detailBtn).toBeVisible({ timeout: 5000 });
|
||||
await detailBtn.click();
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
const recurItem = page
|
||||
.locator('task-detail-item')
|
||||
.filter({ has: page.locator('mat-icon[svgIcon="repeat"]') });
|
||||
await expect(recurItem).toBeVisible({ timeout: 5000 });
|
||||
await recurItem.click();
|
||||
|
||||
// 3. Wait for the repeat dialog and set a future start date
|
||||
// 3. Wait for the repeat dialog and set a future start date via calendar
|
||||
const repeatDialog = page.locator('mat-dialog-container');
|
||||
await repeatDialog.waitFor({ state: 'visible', timeout: 10000 });
|
||||
|
||||
// Set startDate via Angular's dialog component model signal
|
||||
// (mat-datepicker's signal-based inputs don't work from page.evaluate)
|
||||
const futureDate = new Date();
|
||||
futureDate.setMonth(futureDate.getMonth() + 1);
|
||||
futureDate.setDate(15);
|
||||
const year = futureDate.getFullYear();
|
||||
const month = String(futureDate.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(futureDate.getDate()).padStart(2, '0');
|
||||
const futureDateStr = `${year}-${month}-${day}`;
|
||||
// Open the calendar popup
|
||||
const calendarToggle = repeatDialog.locator('mat-datepicker-toggle button');
|
||||
await calendarToggle.click();
|
||||
|
||||
await page.evaluate((dateStr) => {
|
||||
const ng = (window as any).ng;
|
||||
const dialogEl = document.querySelector(
|
||||
'mat-dialog-container dialog-edit-task-repeat-cfg',
|
||||
);
|
||||
if (!ng || !dialogEl) throw new Error('Dialog component not found');
|
||||
const component = ng.getComponent(dialogEl);
|
||||
if (!component) throw new Error('Dialog component instance not found');
|
||||
component.repeatCfg.update((cfg: any) => ({ ...cfg, startDate: dateStr }));
|
||||
}, futureDateStr);
|
||||
await page.waitForTimeout(300);
|
||||
const calendar = page.locator('.mat-calendar');
|
||||
await expect(calendar).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Navigate to next month to ensure the date is in the future
|
||||
const nextMonthBtn = page.getByRole('button', { name: /next month/i });
|
||||
await nextMonthBtn.click();
|
||||
|
||||
// Select the first available day in next month
|
||||
const firstDay = page
|
||||
.locator('.mat-calendar-body-cell:not(.mat-calendar-body-disabled)')
|
||||
.first();
|
||||
await expect(firstDay).toBeVisible({ timeout: 5000 });
|
||||
await firstDay.click();
|
||||
|
||||
// Wait for calendar to close
|
||||
await expect(calendar).not.toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Save the repeat config — wait for the button to be enabled first
|
||||
const saveBtn = repeatDialog.getByRole('button', { name: /Save/i });
|
||||
|
|
@ -72,16 +71,13 @@ test.describe('Recurring Task - Future Start Date (#6856)', () => {
|
|||
await saveBtn.click();
|
||||
await repeatDialog.waitFor({ state: 'hidden', timeout: 10000 });
|
||||
|
||||
// 4. Wait for effects and persistence to process
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
// 5. Reload and navigate to today view to verify persisted state
|
||||
// 4. Reload and navigate to today view to verify persisted state
|
||||
await page.reload();
|
||||
await workViewPage.waitForTaskList();
|
||||
await page.goto('/#/tag/TODAY/tasks');
|
||||
await workViewPage.waitForTaskList();
|
||||
|
||||
// 6. Assert: task should NOT be visible in today's task list
|
||||
// 5. Assert: task should NOT be visible in today's task list
|
||||
// Bug #6856: The task appears immediately instead of being scheduled
|
||||
// for the configured future start date.
|
||||
await expect(taskPage.getTaskByText(taskTitle)).not.toBeVisible({ timeout: 5000 });
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ test.describe('Recurring Task - Start Date Epoch Bug (#6860)', () => {
|
|||
const detailBtn = page.getByRole('button', {
|
||||
name: 'Show/Hide additional info',
|
||||
});
|
||||
await expect(detailBtn).toBeVisible({ timeout: 5000 });
|
||||
await detailBtn.click();
|
||||
|
||||
const recurItem = page
|
||||
|
|
@ -66,28 +67,9 @@ test.describe('Recurring Task - Start Date Epoch Bug (#6860)', () => {
|
|||
expect(inputValue).not.toBe('');
|
||||
expect(inputValue).not.toContain('1970');
|
||||
|
||||
// 6. Also verify via the model that it's not epoch
|
||||
const startDate = await page.evaluate(() => {
|
||||
const ng = (window as any).ng;
|
||||
const dialogEl = document.querySelector(
|
||||
'mat-dialog-container dialog-edit-task-repeat-cfg',
|
||||
);
|
||||
if (!ng || !dialogEl) throw new Error('Dialog component not found');
|
||||
const component = ng.getComponent(dialogEl);
|
||||
if (!component) throw new Error('Dialog component instance not found');
|
||||
return component.repeatCfg().startDate;
|
||||
});
|
||||
|
||||
expect(startDate).toBeDefined();
|
||||
expect(startDate).not.toBe('1970-01-01');
|
||||
|
||||
// The date should be in the future (next month)
|
||||
const today = new Date();
|
||||
const startDateObj = new Date(startDate + 'T00:00:00');
|
||||
expect(startDateObj.getTime()).toBeGreaterThan(today.getTime());
|
||||
|
||||
// 7. Save and verify the date survives persistence
|
||||
// 6. Save and verify the date survives persistence
|
||||
const saveBtn = repeatDialog.getByRole('button', { name: /Save/i });
|
||||
await expect(saveBtn).toBeEnabled({ timeout: 5000 });
|
||||
await saveBtn.click();
|
||||
await repeatDialog.waitFor({ state: 'hidden', timeout: 10000 });
|
||||
});
|
||||
|
|
@ -112,6 +94,7 @@ test.describe('Recurring Task - Start Date Epoch Bug (#6860)', () => {
|
|||
const detailBtn = page.getByRole('button', {
|
||||
name: 'Show/Hide additional info',
|
||||
});
|
||||
await expect(detailBtn).toBeVisible({ timeout: 5000 });
|
||||
await detailBtn.click();
|
||||
|
||||
const recurItem = page
|
||||
|
|
@ -128,8 +111,10 @@ test.describe('Recurring Task - Start Date Epoch Bug (#6860)', () => {
|
|||
// The app defaults to en-GB locale (DD/MM/YYYY format)
|
||||
const dateInput = repeatDialog.getByRole('textbox', { name: /start date/i });
|
||||
await expect(dateInput).toBeVisible();
|
||||
await dateInput.clear();
|
||||
await dateInput.fill('15/06/2026');
|
||||
// Click to focus the input, then select all and type the date
|
||||
await dateInput.click();
|
||||
await dateInput.press('Control+a');
|
||||
await dateInput.pressSequentially('15/06/2026', { delay: 50 });
|
||||
// Trigger change by pressing Tab to blur
|
||||
await dateInput.press('Tab');
|
||||
|
||||
|
|
@ -138,23 +123,9 @@ test.describe('Recurring Task - Start Date Epoch Bug (#6860)', () => {
|
|||
expect(inputValue).not.toBe('');
|
||||
expect(inputValue).not.toContain('1970');
|
||||
|
||||
// 6. Verify via model that the date was preserved
|
||||
const startDate = await page.evaluate(() => {
|
||||
const ng = (window as any).ng;
|
||||
const dialogEl = document.querySelector(
|
||||
'mat-dialog-container dialog-edit-task-repeat-cfg',
|
||||
);
|
||||
if (!ng || !dialogEl) throw new Error('Dialog component not found');
|
||||
const component = ng.getComponent(dialogEl);
|
||||
if (!component) throw new Error('Dialog component instance not found');
|
||||
return component.repeatCfg().startDate;
|
||||
});
|
||||
|
||||
expect(startDate).toBeDefined();
|
||||
expect(startDate).not.toBe('1970-01-01');
|
||||
|
||||
// 7. Save
|
||||
// 6. Save
|
||||
const saveBtn = repeatDialog.getByRole('button', { name: /Save/i });
|
||||
await expect(saveBtn).toBeEnabled({ timeout: 5000 });
|
||||
await saveBtn.click();
|
||||
await repeatDialog.waitFor({ state: 'hidden', timeout: 10000 });
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue