microsoft / playwright-pytest

Pytest plugin to write end-to-end browser tests with Playwright.
https://playwright.dev/python/docs/test-runners
Apache License 2.0
444 stars 69 forks source link

[BUG]PermissionError: [WinError 5] #224

Closed zhaod34 closed 5 months ago

zhaod34 commented 7 months ago

Context

windows 11
python 3.12.2
pytest 7.4
playwright-pytest 0.4.4
pytest-xdist 3.5.0

run pytest -n 3 test_case

Sometimes report the error:


[gw1] win32 -- Python 3.12.2 C:\Users\Administrator\.virtualenvs\ehr_autotest-ViGcsCVN\Scripts\python.exe

pytestconfig = <_pytest.config.Config object at 0x000001C68B1B51C0>

    @pytest.fixture(scope="session", autouse=True)
    def delete_output_dir(pytestconfig: Any) -> None:
        output_dir = pytestconfig.getoption("--output")
        if os.path.exists(output_dir):
            try:
>               shutil.rmtree(output_dir)

C:\Users\Administrator\.virtualenvs\ehr_autotest-ViGcsCVN\Lib\site-packages\pytest_playwright\pytest_playwright.py:45:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _  
..\..\Python312\Lib\shutil.py:820: in rmtree
    return _rmtree_unsafe(path, onexc)
..\..\Python312\Lib\shutil.py:643: in _rmtree_unsafe
    _rmtree_unsafe(fullname, onexc)
..\..\Python312\Lib\shutil.py:652: in _rmtree_unsafe
    onexc(os.rmdir, path, err)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

path = 'test-results\\test-case-organization-organization-test-add-organization-py-test-add-organization-default-user-chromium'
onexc = <function rmtree.<locals>.onexc at 0x000001C69C85E020>

    def _rmtree_unsafe(path, onexc):
        try:
            with os.scandir(path) as scandir_it:
                entries = list(scandir_it)
        except OSError as err:
            onexc(os.scandir, path, err)
            entries = []
        for entry in entries:
            fullname = entry.path
            try:
                is_dir = entry.is_dir(follow_symlinks=False)
            except OSError:
                is_dir = False

            if is_dir and not entry.is_junction():
                try:
                    if entry.is_symlink():
                        # This can only happen if someone replaces
                        # a directory with a symlink after the call to
                        # os.scandir or entry.is_dir above.
                        raise OSError("Cannot call rmtree on a symbolic link")
                except OSError as err:
                    onexc(os.path.islink, fullname, err)
                    continue
                _rmtree_unsafe(fullname, onexc)
            else:
                try:
                    os.unlink(fullname)
                except OSError as err:
                    onexc(os.unlink, fullname, err)
        try:
>           os.rmdir(path)
E           PermissionError: [WinError 5] 拒绝访问。: 'test-results\\test-case-organization-organization-test-add-organization-py-test-add-organization-default-user-chromium'

..\..\Python312\Lib\shutil.py:650: PermissionError
andreabisello commented 5 months ago

@zhaod34 i'm obtaining the same problem (access denied),

PermissionError: [WinError 5] Accesso negato: 'test-results\test-test-browser-test-user-test-megasearch-test-content-visualization-py-testcontentvisualization-test-content-visualization-with-docuviewer-chromium-pdf\video-1.webm'

that's happening because of xdist,

indeed even if there is the exception,

the folder is deleted,

that means that xdist, spawning different processes, is trying to delete the same files simuntaneally to other xdist processes,

i'm tring to use one of the pytest webhook to empty the folder.

did you found another solution in the meanwhile?

andreabisello commented 5 months ago

for now i'm using this workaround


def pytest_sessionstart(session):
    """
    at the very beginning
    """
    print("deleting folder containing video results, if exists")
    temptative = 0
    while temptative < 3 and os.path.exists('test-results'):
        try:
            shutil.rmtree('test-results')
        except Exception as e:
            print("retrying")
        time.sleep(1)
        temptative =+ 1
    print("folder deleted.")
nck974 commented 5 months ago

I have the same issue also using xdist. The workaround is rerunning the tests again as the folder is deleted and in the second run you do not see the error. But it wastes a lot of time.

mxschmitt commented 5 months ago

This should be fixed in v0.5.1 which is getting published rn. Thanks to @nck974.