diff --git a/src/bidiMapper/modules/browser/BrowserProcessor.ts b/src/bidiMapper/modules/browser/BrowserProcessor.ts index 2acf6d9d9..52003ba8e 100644 --- a/src/bidiMapper/modules/browser/BrowserProcessor.ts +++ b/src/bidiMapper/modules/browser/BrowserProcessor.ts @@ -113,7 +113,7 @@ export class BrowserProcessor { {targetId}, ); return { - // Is not supported in CDP yet. + // `active` is not supported in CDP yet. active: false, clientWindow: `${windowInfo.windowId}`, state: windowInfo.bounds.windowState ?? 'normal', @@ -134,6 +134,17 @@ export class BrowserProcessor { async (targetId) => await this.#getWindowInfo(targetId), ), ); - return {clientWindows}; + + const uniqueClientWindowIds = new Set(); + const uniqueClientWindows = new Array(); + + // Filter out duplicated client windows. + for (const window of clientWindows) { + if (!uniqueClientWindowIds.has(window.clientWindow)) { + uniqueClientWindowIds.add(window.clientWindow); + uniqueClientWindows.push(window); + } + } + return {clientWindows: uniqueClientWindows}; } } diff --git a/tests/browser/test_get_client_windows.py b/tests/browser/test_get_client_windows.py index 4582b3496..4e8edf028 100644 --- a/tests/browser/test_get_client_windows.py +++ b/tests/browser/test_get_client_windows.py @@ -19,7 +19,7 @@ @pytest.mark.asyncio -async def test_browser_get_client_windows(websocket, context_id): +async def test_browser_get_client_windows_single_tab(websocket, context_id): resp = await execute_command(websocket, { "method": "browser.getClientWindows", "params": {} @@ -27,7 +27,71 @@ async def test_browser_get_client_windows(websocket, context_id): assert resp == { 'clientWindows': [ { - # Not implemented yet + # `active` is not implemented yet + 'active': False, + 'clientWindow': ANY_STR, + 'height': ANY_NUMBER, + 'state': 'normal', + 'width': ANY_NUMBER, + 'x': ANY_NUMBER, + 'y': ANY_NUMBER, + }, + ], + } + + +@pytest.mark.asyncio +async def test_browser_get_client_windows_two_tabs(websocket, context_id, + create_context, + test_headless_mode): + if test_headless_mode == "old": + pytest.xfail("In old headless mode, each tab is in a separate window") + + await create_context(context_type='tab') + + resp = await execute_command(websocket, { + "method": "browser.getClientWindows", + "params": {} + }) + assert resp == { + 'clientWindows': [ + { + # `active` is not implemented yet + 'active': False, + 'clientWindow': ANY_STR, + 'height': ANY_NUMBER, + 'state': 'normal', + 'width': ANY_NUMBER, + 'x': ANY_NUMBER, + 'y': ANY_NUMBER, + }, + ], + } + + +@pytest.mark.asyncio +async def test_browser_get_client_windows_two_windows(websocket, context_id, + create_context): + await create_context(context_type='window') + + resp = await execute_command(websocket, { + "method": "browser.getClientWindows", + "params": {} + }) + assert resp == { + 'clientWindows': [ + { + # `active` is not implemented yet + 'active': False, + 'clientWindow': ANY_STR, + 'height': ANY_NUMBER, + 'state': 'normal', + 'width': ANY_NUMBER, + 'x': ANY_NUMBER, + 'y': ANY_NUMBER, + }, + { + # `active` is not implemented yet 'active': False, 'clientWindow': ANY_STR, 'height': ANY_NUMBER, diff --git a/tests/conftest.py b/tests/conftest.py index 65f4e83ac..d73045916 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -174,12 +174,12 @@ async def another_context_id(create_context): @pytest_asyncio.fixture def create_context(websocket): """Return a browsing context factory.""" - async def create_context(user_context_id=None): + async def create_context(user_context_id=None, context_type='tab'): result = await execute_command( websocket, { "method": "browsingContext.create", "params": { - "type": "tab" + "type": context_type } | ({ "userContext": user_context_id } if user_context_id is not None else {})