Repository: microsoft/playwright-pytest (language: python)

Issue:
[Question] How to make the context with funciton 'launch_persistent_context'
How to make the context with funciton 'launch_persistent_context'? I want to set `user_data_dir` in browser context, How can I do it?

Thanks!


Discussion / hints:
You can use a fixture like that, this will make that all the pages inside your test are created from the persistent context:

```py
import pytest
from playwright.sync_api import BrowserType, Playwright
from typing import Dict

@pytest.fixture(scope="session")
def context(
    playwright: Playwright,
    browser_name: str,
    browser_type_launch_args: Dict,
    browser_context_args: Dict
):
    context = getattr(playwright, browser_name).launch_persistent_context("./foobar", **{
        **browser_type_launch_args,
        **browser_context_args,
        "locale": "de-DE",
    })
    yield context
    context.close()
```

Fix patch:
diff --git a/README.md b/README.md
index 72990e6..80d45d4 100644
--- a/README.md
+++ b/README.md
@@ -15,6 +15,7 @@ pip install pytest-playwright
 Use the `page` fixture to write a basic test. See [more examples](#examples).
 
 ```py
+# test_my_application.py
 def test_example_is_working(page):
     page.goto("https://example.com")
     assert page.inner_text('h1') == 'Example Domain'
@@ -77,6 +78,7 @@ def test_my_app_is_working(fixture_name):
 ### Configure Mypy typings for auto-completion
 
 ```py
+# test_my_application.py
 from playwright.sync_api import Page
 
 def test_visit_admin_dashboard(page: Page):
@@ -95,6 +97,7 @@ pytest --slowmo 100
 ### Skip test by browser
 
 ```py
+# test_my_application.py
 import pytest
 
 @pytest.mark.skip_browser("firefox")
@@ -106,6 +109,7 @@ def test_visit_example(page):
 ### Run on a specific browser
 
 ```py
+# conftest.py
 import pytest
 
 @pytest.mark.only_browser("chromium")
@@ -121,6 +125,7 @@ pytest --browser-channel chrome # or chrome-beta, chrome-dev, chrome-canary, mse
 ```
 
 ```python
+# test_my_application.py
 def test_example(page):
     page.goto("https://example.com")
 ```
@@ -134,6 +139,7 @@ pytest --base-url http://localhost:8080
 ```
 
 ```py
+# test_my_application.py
 def test_visit_example(page):
     page.goto("/admin")
     # -> Will result in http://localhost:8080/admin
@@ -141,9 +147,8 @@ def test_visit_example(page):
 
 ### Ignore HTTPS errors
 
-conftest.py
-
 ```py
+# conftest.py
 import pytest
 
 @pytest.fixture(scope="session")
@@ -156,9 +161,8 @@ def browser_context_args(browser_context_args):
 
 ### Use custom viewport size
 
-conftest.py
-
 ```py
+# conftest.py
 import pytest
 
 @pytest.fixture(scope="session")
@@ -174,9 +178,8 @@ def browser_context_args(browser_context_args):
 
 ### Device emulation
 
-conftest.py
-
 ```py
+# conftest.py
 import pytest
 
 @pytest.fixture(scope="session")
@@ -188,6 +191,31 @@ def browser_context_args(browser_context_args, playwright):
     }
 ```
 
+### Persistent context
+
+```py
+# conftest.py
+import pytest
+from playwright.sync_api import BrowserType
+from typing import Dict
+
+@pytest.fixture(scope="session")
+def context(
+    browser_type: BrowserType,
+    browser_type_launch_args: Dict,
+    browser_context_args: Dict
+):
+    context = browser_type.launch_persistent_context("./foobar", **{
+        **browser_type_launch_args,
+        **browser_context_args,
+        "locale": "de-DE",
+    })
+    yield context
+    context.close()
+```
+
+When using that all pages inside your test are created from the persistent context.
+
 ## Debugging
 
 ### Use with pdb
@@ -208,7 +236,7 @@ You can capture screenshots for failed tests with a [pytest runtest hook](https:
 Note that this snippet uses `slugify` to convert test names to file paths, which can be installed with `pip install python-slugify`.
 
 ```py
-# In conftest.py
+# conftest.py
 from slugify import slugify
 from pathlib import Path
 


Test patch:
diff --git a/pytest_playwright/pytest_playwright.py b/pytest_playwright/pytest_playwright.py
index 8630628..0ee236e 100644
--- a/pytest_playwright/pytest_playwright.py
+++ b/pytest_playwright/pytest_playwright.py
@@ -23,6 +23,7 @@
     Page,
     Playwright,
     sync_playwright,
+    BrowserType,
 )
 
 
@@ -85,8 +86,18 @@ def event_loop() -> Generator[AbstractEventLoop, None, None]:
 
 
 @pytest.fixture(scope="session")
-def browser_type_launch_args() -> Dict:
-    return {}
+def browser_type_launch_args(pytestconfig: Any) -> Dict:
+    launch_options = {}
+    headed_option = pytestconfig.getoption("--headed")
+    if headed_option:
+        launch_options["headless"] = False
+    browser_channel_option = pytestconfig.getoption("--browser-channel")
+    if browser_channel_option:
+        launch_options["channel"] = browser_channel_option
+    slowmo_option = pytestconfig.getoption("--slowmo")
+    if slowmo_option:
+        launch_options["slow_mo"] = slowmo_option
+    return launch_options
 
 
 @pytest.fixture(scope="session")
@@ -101,27 +112,20 @@ def playwright() -> Generator[Playwright, None, None]:
     pw.stop()
 
 
+@pytest.fixture(scope="session")
+def browser_type(playwright: Playwright, browser_name: str) -> BrowserType:
+    return getattr(playwright, browser_name)
+
+
 @pytest.fixture(scope="session")
 def launch_browser(
-    pytestconfig: Any,
     playwright: Playwright,
     browser_type_launch_args: Dict,
-    browser_name: str,
+    browser_type: BrowserType,
 ) -> Callable[..., Browser]:
     def launch(**kwargs: Dict) -> Browser:
         launch_options = {**browser_type_launch_args, **kwargs}
-
-        headed_option = pytestconfig.getoption("--headed")
-        if headed_option:
-            launch_options["headless"] = False
-        browser_channel_option = pytestconfig.getoption("--browser-channel")
-        if browser_channel_option:
-            launch_options["channel"] = browser_channel_option
-        slowmo_option = pytestconfig.getoption("--slowmo")
-        if slowmo_option:
-            launch_options["slow_mo"] = slowmo_option
-
-        browser = getattr(playwright, browser_name).launch(**launch_options)
+        browser = browser_type.launch(**launch_options)
         return browser
 
     return launch
diff --git a/tests/test_playwright.py b/tests/test_playwright.py
index eb28f2e..e09cef0 100644
--- a/tests/test_playwright.py
+++ b/tests/test_playwright.py
@@ -292,3 +292,35 @@ def test_browser_context_args(page):
     )
     result = testdir.runpytest()
     result.assert_outcomes(passed=1)
+
+
+def test_launch_persistent_context(testdir: Any) -> None:
+    testdir.makeconftest(
+        """
+        import pytest
+        from playwright.sync_api import BrowserType
+        from typing import Dict
+
+        @pytest.fixture(scope="session")
+        def context(
+            browser_type: BrowserType,
+            browser_type_launch_args: Dict,
+            browser_context_args: Dict
+        ):
+            context = browser_type.launch_persistent_context("./foobar", **{
+                **browser_type_launch_args,
+                **browser_context_args,
+                "locale": "de-DE",
+            })
+            yield context
+            context.close()
+    """
+    )
+    testdir.makepyfile(
+        """
+        def test_browser_context_args(page):
+            assert page.evaluate("navigator.language") == "de-DE"
+    """
+    )
+    result = testdir.runpytest()
+    result.assert_outcomes(passed=1)