diff --git a/examples/todomvc/tests/integration.spec.ts b/examples/todomvc/tests/integration.spec.ts index 007896bb2c..b438a13d15 100644 --- a/examples/todomvc/tests/integration.spec.ts +++ b/examples/todomvc/tests/integration.spec.ts @@ -54,6 +54,58 @@ test.describe('New Todo', () => { await checkNumberOfTodosInLocalStorage(page, 1); }); + test('should clear text input field when an item is added 3', async ({ page }) => { + // create a new todo locator + const newTodo = page.getByPlaceholder('What needs to be done?'); + + // Create one todo item. + await newTodo.fill(TODO_ITEMS[0]); + await newTodo.press('Enter'); + + // Check that input is empty. + await expect(newTodo).toBeEmpty(); + await checkNumberOfTodosInLocalStorage(page, 1); + }); + + test('should clear text input field when an item is added 4', async ({ page }) => { + // create a new todo locator + const newTodo = page.getByPlaceholder('What needs to be done?'); + + // Create one todo item. + await newTodo.fill(TODO_ITEMS[0]); + await newTodo.press('Enter'); + + // Check that input is empty. + await expect(newTodo).toBeEmpty(); + await checkNumberOfTodosInLocalStorage(page, 1); + }); + + test('should clear text input field when an item is added 5', async ({ page }) => { + // create a new todo locator + const newTodo = page.getByPlaceholder('What needs to be done?'); + + // Create one todo item. + await newTodo.fill(TODO_ITEMS[0]); + await newTodo.press('Enter'); + + // Check that input is empty. + await expect(newTodo).toBeEmpty(); + await checkNumberOfTodosInLocalStorage(page, 1); + }); + + test('should clear text input field when an item is added 2', async ({ page }) => { + // create a new todo locator + const newTodo = page.getByPlaceholder('What needs to be done?'); + + // Create one todo item. + await newTodo.fill(TODO_ITEMS[0]); + await newTodo.press('Enter'); + + // Check that input is empty. + await expect(newTodo).toBeEmpty(); + await checkNumberOfTodosInLocalStorage(page, 1); + }); + test('should append new items to the bottom of the list', async ({ page }) => { // Create 3 items. await createDefaultTodos(page); @@ -351,6 +403,22 @@ test.describe('Routing', () => { await expect(page.getByTestId('todo-item')).toHaveText([TODO_ITEMS[0], TODO_ITEMS[2]]); }); + test('should allow me to display active items 2', async ({ page }) => { + await page.locator('.todo-list li .toggle').nth(1).check(); + await checkNumberOfCompletedTodosInLocalStorage(page, 1); + await page.getByRole('link', { name: 'Active' }).click(); + await expect(page.getByTestId('todo-item')).toHaveCount(2); + await expect(page.getByTestId('todo-item')).toHaveText([TODO_ITEMS[0], TODO_ITEMS[2]]); + }); + + test('should allow me to display active items 3', async ({ page }) => { + await page.locator('.todo-list li .toggle').nth(1).check(); + await checkNumberOfCompletedTodosInLocalStorage(page, 1); + await page.getByRole('link', { name: 'Active' }).click(); + await expect(page.getByTestId('todo-item')).toHaveCount(2); + await expect(page.getByTestId('todo-item')).toHaveText([TODO_ITEMS[0], TODO_ITEMS[2]]); + }); + test('should respect the back button', async ({ page }) => { await page.locator('.todo-list li .toggle').nth(1).check(); await checkNumberOfCompletedTodosInLocalStorage(page, 1); @@ -429,3 +497,4 @@ async function checkTodosInLocalStorage(page: Page, title: string) { return JSON.parse(localStorage['react-todos']).map((todo: any) => todo.title).includes(t); }, title); } + diff --git a/packages/playwright-core/src/client/browserContext.ts b/packages/playwright-core/src/client/browserContext.ts index f8f8977313..3f5640789e 100644 --- a/packages/playwright-core/src/client/browserContext.ts +++ b/packages/playwright-core/src/client/browserContext.ts @@ -445,6 +445,9 @@ export class BrowserContext extends ChannelOwner return; this._closeReason = options.reason; this._closeWasCalled = true; + await this._wrapApiCall(async () => { + await this.request.dispose(options); + }, true); await this._wrapApiCall(async () => { await this._browserType?._willCloseContext(this); for (const [harId, harParams] of this._harRecorders) { diff --git a/packages/playwright-core/src/client/fetch.ts b/packages/playwright-core/src/client/fetch.ts index 34f0af3eae..2b32617f5b 100644 --- a/packages/playwright-core/src/client/fetch.ts +++ b/packages/playwright-core/src/client/fetch.ts @@ -103,7 +103,13 @@ export class APIRequestContext extends ChannelOwner { this._closeReason = options.reason; await this._instrumentation.onWillCloseRequestContext(this); - await this._channel.dispose(options); + try { + await this._channel.dispose(options); + } catch (e) { + if (isTargetClosedError(e)) + return; + throw e; + } this._tracing._resetStackCounter(); this._request?._contexts.delete(this); } diff --git a/tests/library/browsercontext-fetch.spec.ts b/tests/library/browsercontext-fetch.spec.ts index e4d7a6dbf3..f4088359cf 100644 --- a/tests/library/browsercontext-fetch.spec.ts +++ b/tests/library/browsercontext-fetch.spec.ts @@ -1255,3 +1255,8 @@ it('should not work after dispose', async ({ context, server }) => { await context.request.dispose(); expect(await context.request.get(server.EMPTY_PAGE).catch(e => e.message)).toContain(kTargetClosedErrorMessage); }); + +it('should not work after context dispose', async ({ context, server }) => { + await context.close({ reason: 'Test ended.' }); + expect(await context.request.get(server.EMPTY_PAGE).catch(e => e.message)).toContain('Test ended.'); +});