Repository: napari/napari

Issue:
Replace GabrielBB/xvfb-action with something that will work after node 12 removal from GHA runners
## 🧰 Task
<!-- A clear and concise description of the task -->

For some time the GHA emits warnings about node 12 deprecation:

![obraz](https://user-images.githubusercontent.com/3826210/212340731-f7d0b13d-de57-4dbc-af27-6a750d774393.png)

Also `GabrielBB/xvfb-action` looks unmaintained https://github.com/GabrielBB/xvfb-action/issues/30. 

It means that at some moment it will stop working. 

It requires some action from our side:

1) We should either create own fork of this action and update it (maybe handle also herbstluftwm in such action see https://github.com/napari/napari/pull/5208#discussion_r1054604590) or switch to existing fork ex. https://github.com/coactions/setup-xvfb) 

2) Migrate all our repositories to a new action. 

3) Widely advertises such migrations in the whole napari community to reach plugin developers. 


Migrated from #5208


Discussion:

Resolving patch:
diff --git a/napari/utils/_testsupport.py b/napari/utils/_testsupport.py
--- a/napari/utils/_testsupport.py
+++ b/napari/utils/_testsupport.py
@@ -1,10 +1,7 @@
 import collections
 import gc
 import os
-import platform
-import subprocess
 import sys
-import time
 import warnings
 from contextlib import suppress
 from typing import TYPE_CHECKING
@@ -362,41 +359,3 @@ def MouseEvent():
             'dims_point',
         ],
     )
-
-
-@pytest.fixture
-def linux_wm():
-    """Start a WM in the background for tests that need a WM.
-
-    This is required for tests that depend on UI events (e.g. setFocus).
-    See https://github.com/pytest-dev/pytest-qt/issues/206.
-
-    This will only run on Linux and in CI (determined by CI env var) - this is
-    unnecessary/irrelevant on macOS and Windows.
-
-    The window manager start command can be set via env var `WM_START_CMD`
-    (default is `herbstluftwm` - make sure it's installed).
-    """
-    wm_start_cmd = os.environ.get("WM_START_CMD", "herbstluftwm")
-    proc = None
-    if platform.system() == "Linux" and os.environ.get("CI"):
-        proc = subprocess.Popen([wm_start_cmd])
-        # give the WM 1s to start up and check it's still running
-        time.sleep(1)
-        if proc.poll() is not None:
-            raise RuntimeError(
-                f"window manager '{wm_start_cmd}' process [{proc.pid}] exited, "
-                f"return code: {proc.returncode}"
-            )
-
-    yield proc
-
-    if proc:
-        proc.terminate()
-        try:
-            proc.wait(timeout=20)
-        except subprocess.TimeoutExpired:
-            proc.kill()
-            raise RuntimeError(
-                f"failed to terminate window manager '{wm_start_cmd}'"
-            )


Test patch:
diff --git a/.github/workflows/test_comprehensive.yml b/.github/workflows/test_comprehensive.yml
--- a/.github/workflows/test_comprehensive.yml
+++ b/.github/workflows/test_comprehensive.yml
@@ -85,12 +85,6 @@ jobs:
           powershell gl-ci-helpers/appveyor/install_opengl.ps1
           if (Test-Path -Path "C:\Windows\system32\opengl32.dll" -PathType Leaf) {Exit 0} else {Exit 1}
 
-      # run a minimal wm for linux tests that depend on UI events (e.g. setFocus)
-      # see https://github.com/pytest-dev/pytest-qt/issues/206
-      - name: Install WM on Linux
-        if: runner.os == 'Linux'
-        run: sudo apt-get update && sudo apt-get install -y herbstluftwm
-
       - name: Install dependencies
         run: |
           pip install --upgrade pip
@@ -106,7 +100,7 @@ jobs:
       # in which case we are declaring one specific tox environment to run.
       # see tox.ini for more
       - name: Test with tox
-        uses: GabrielBB/xvfb-action@v1
+        uses: aganders3/headless-gui@v1
         with:
           run: python -m tox
         env:
@@ -151,17 +145,13 @@ jobs:
 
       - uses: tlambert03/setup-qt-libs@v1
 
-      - name: Install WM
-        if: runner.os == 'Linux'
-        run: sudo apt-get update && sudo apt-get install -y herbstluftwm
-
       - name: Install this commit
         run: |
           pip install --upgrade pip
           pip install ./napari-from-github[all,testing]
 
       - name: Test
-        uses: GabrielBB/xvfb-action@v1
+        uses: aganders3/headless-gui@v1
         with:
           run: python -m pytest --pyargs napari --color=yes
 
@@ -180,6 +170,6 @@ jobs:
           pip install setuptools tox tox-gh-actions
 
       - name: Test
-        uses: GabrielBB/xvfb-action@v1
+        uses: aganders3/headless-gui@v1
         with:
           run: tox -e py39-linux-pyside2-examples
diff --git a/.github/workflows/test_prereleases.yml b/.github/workflows/test_prereleases.yml
--- a/.github/workflows/test_prereleases.yml
+++ b/.github/workflows/test_prereleases.yml
@@ -39,12 +39,6 @@ jobs:
           powershell gl-ci-helpers/appveyor/install_opengl.ps1
           if (Test-Path -Path "C:\Windows\system32\opengl32.dll" -PathType Leaf) {Exit 0} else {Exit 1}
 
-      # run a minimal wm for linux tests that depend on UI events (e.g. setFocus)
-      # see https://github.com/pytest-dev/pytest-qt/issues/206
-      - name: Install WM on Linux
-        if: runner.os == 'Linux'
-        run: sudo apt-get update && sudo apt-get install -y herbstluftwm
-
       - name: Install dependencies
         run: |
           pip install --upgrade pip
@@ -52,7 +46,7 @@ jobs:
 
       - name: Test with tox
         # run tests using pip install --pre
-        uses: GabrielBB/xvfb-action@v1
+        uses: aganders3/headless-gui@v1
         with:
           run: python -m tox -v --pre
         env:
diff --git a/.github/workflows/test_pull_requests.yml b/.github/workflows/test_pull_requests.yml
--- a/.github/workflows/test_pull_requests.yml
+++ b/.github/workflows/test_pull_requests.yml
@@ -114,12 +114,6 @@ jobs:
           powershell gl-ci-helpers/appveyor/install_opengl.ps1
           if (Test-Path -Path "C:\Windows\system32\opengl32.dll" -PathType Leaf) {Exit 0} else {Exit 1}
 
-      # run a minimal wm for linux tests that depend on UI events (e.g. setFocus)
-      # see https://github.com/pytest-dev/pytest-qt/issues/206
-      - name: Install WM on Linux
-        if: runner.os == 'Linux'
-        run: sudo apt-get update && sudo apt-get install -y herbstluftwm
-
       # tox and tox-gh-actions will take care of the "actual" installation
       # of python dependendencies into a virtualenv.  see tox.ini for more
       - name: Install dependencies
@@ -140,7 +134,7 @@ jobs:
       # `tox -e py38-linux-pyqt,py38-linux-pyside`
       # see tox.ini for more
       - name: Test with tox
-        uses: GabrielBB/xvfb-action@v1
+        uses: aganders3/headless-gui@v1
         with:
           run: python -m tox
         env:
@@ -176,19 +170,13 @@ jobs:
 
       - uses: tlambert03/setup-qt-libs@v1
 
-      # run a minimal wm for linux tests that depend on UI events (e.g. setFocus)
-      # see https://github.com/pytest-dev/pytest-qt/issues/206
-      - name: Install WM
-        if: runner.os == 'Linux'
-        run: sudo apt-get update && sudo apt-get install -y herbstluftwm
-
       - name: Install this commit
         run: |
           pip install --upgrade pip
           pip install ./napari-from-github[all,testing]
 
       - name: Test
-        uses: GabrielBB/xvfb-action@v1
+        uses: aganders3/headless-gui@v1
         with:
           run: |
             python -m pytest --pyargs napari --color=yes
@@ -210,6 +198,6 @@ jobs:
           pip install setuptools tox tox-gh-actions
 
       - name: Test
-        uses: GabrielBB/xvfb-action@v1
+        uses: aganders3/headless-gui@v1
         with:
           run: tox -e py39-linux-pyside2-examples
diff --git a/napari/_qt/_tests/test_qt_viewer.py b/napari/_qt/_tests/test_qt_viewer.py
--- a/napari/_qt/_tests/test_qt_viewer.py
+++ b/napari/_qt/_tests/test_qt_viewer.py
@@ -66,7 +66,7 @@ def test_qt_viewer_toggle_console(make_napari_viewer):
 
 
 @skip_local_popups
-def test_qt_viewer_console_focus(qtbot, make_napari_viewer, linux_wm):
+def test_qt_viewer_console_focus(qtbot, make_napari_viewer):
     """Test console has focus when instantiating from viewer."""
     viewer = make_napari_viewer(show=True)
     view = viewer.window._qt_viewer