diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 921c235d4c..905ee415d2 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -38,14 +38,75 @@ jobs:
# Ref: https://github.com/rdmorganiser/.github/blob/main/.github/workflows/_lint.yml
uses: rdmorganiser/.github/.github/workflows/_lint.yml@main
+ build-wheel:
+ name: Build python wheel
+ runs-on: ubuntu-24.04
+ steps:
+ - uses: actions/checkout@v4
+ # update the version
+ - name: Get short commit SHA
+ run: |
+ if [ "${{ github.event_name }}" = "pull_request" ]; then
+ SHA="${{ github.event.pull_request.head.sha }}"
+ else
+ SHA="${{ github.sha }}"
+ fi
+ echo "SHA=$(git rev-parse --short $SHA)" >> $GITHUB_ENV
+ - name: Get current version (MAJOR.MINOR.PATCH)
+ id: current-version
+ run: echo "current_version=$(grep -Po '(?<=__version__ = ")[\d\w.]+(?=")' rdmo/__init__.py)" >> $GITHUB_OUTPUT
+ - name: Generate new version (current version + SHA)
+ id: new-version
+ run: echo "new_version=${{ steps.current-version.outputs.current_version }}+$SHA" >> $GITHUB_OUTPUT
+ - name: Update version in rdmo/__init__.py
+ run: |
+ sed -i "s/__version__ = .*/__version__ = \"${{ steps.new-version.outputs.new_version }}\"/" rdmo/__init__.py
+ # build the webpack bundle
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 18
+ cache: npm
+ - run: npm install && npm run build:prod
+ # build the wheel
+ - uses: actions/setup-python@v5
+ with:
+ python-version: '3.12'
+ cache: pip
+ - run: |
+ python -m pip install --upgrade pip build[uv] twine
+ python -m pip --version
+ - name: Build the wheel
+ run: python -m build --installer=uv
+ - name: Check the metadata of wheel and sdist
+ run: python -m twine check --strict dist/*
+ - name: Install package from built wheel
+ run: python -m pip install --no-compile dist/rdmo*.whl # do not create __pycache__/*.pyc files
+ - name: Write info to step summary
+ run: |
+ {
+ echo -e "# ✓ Wheel successfully built (v${{ steps.new-version.outputs.new_version }})\n\n"
+ echo 'Information about installed wheel
'
+ echo -e "\n\`\`\`console"
+ echo "$ python -m pip show --files --verbose rdmo"
+ python -m pip show --files --verbose rdmo
+ echo -e "\`\`\`\n "
+ } >> $GITHUB_STEP_SUMMARY
+ - name: Upload wheel as artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: wheel
+ path: dist/rdmo*.whl
+ if-no-files-found: error
+ retention-days: 30
+
test:
+ name: "Test (Python: ${{ matrix.python-version }}, DB: ${{ matrix.db-backend }})"
+ needs: build-wheel
runs-on: ubuntu-24.04
strategy:
matrix:
python-version: ['3.8', '3.12']
db-backend: [mysql, postgres]
- name: "Test (Python: ${{ matrix.python-version }}, DB: ${{ matrix.db-backend }})"
- needs: lint
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
@@ -53,32 +114,35 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
cache: pip
+ - name: Download wheel
+ uses: actions/download-artifact@v4
+ with:
+ name: wheel
+ path: dist
- name: Install Dependencies
run: |
- sudo apt update
- sudo apt install --yes pandoc texlive-xetex librsvg2-bin
- python -m pip install --upgrade pip
+ sudo apt-get update && sudo apt-get install --yes pandoc texlive-xetex librsvg2-bin
pandoc --version
- - name: Install rdmo[mysql] and start mysql
+ python -m pip install --upgrade pip
+ python -m pip --version
+ - name: Install rdmo[mysql] from wheel and start mysql
run: |
- python -m pip install --editable .[ci,mysql]
+ python -m pip install "$(ls dist/*.whl)[ci,mysql]"
sudo systemctl start mysql.service
if: matrix.db-backend == 'mysql'
- - name: Install rdmo[postgres] and start postgresql
+ - name: Install rdmo[postgres] from wheel and start postgresql
run: |
- python -m pip install --editable .[ci,postgres]
+ python -m pip install "$(ls dist/*.whl)[ci,postgres]"
sudo systemctl start postgresql.service
pg_isready
sudo -u postgres psql --command="CREATE USER postgres_user PASSWORD 'postgres_password' CREATEDB"
if: matrix.db-backend == 'postgres'
- name: Prepare Env
run: |
- cp -r testing/media testing/media_root
- mkdir testing/log
+ cp -r testing/media testing/media_root && mkdir testing/log
- name: Run package status tests first
run: |
- pytest rdmo/core/tests/test_package_status.py::test_package_json_and_pre_commit_versions_match \
- --nomigrations --verbose
+ pytest rdmo/core/tests/test_package_status.py --nomigrations --verbose
if: matrix.python-version == '3.12' && matrix.db-backend == 'postgres'
- name: Run Tests
run: |
@@ -90,22 +154,48 @@ jobs:
with:
flag-name: '${{ matrix.db-backend }}: ${{ matrix.python-version }}'
parallel: true
- # end-to-end tests
- - uses: actions/setup-node@v4
+
+ test-e2e:
+ name: "End-to-end Test (Python: ${{ matrix.python-version }}, DB: ${{ matrix.db-backend }})"
+ needs: build-wheel
+ runs-on: ubuntu-24.04
+ strategy:
+ matrix:
+ python-version: ['3.12']
+ db-backend: [postgres]
+ steps:
+ - uses: actions/checkout@v4
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v5
with:
- node-version: 18
- cache: npm
- if: matrix.python-version == '3.12' && matrix.db-backend == 'postgres'
+ python-version: ${{ matrix.python-version }}
+ cache: pip
+ - name: Download wheel
+ uses: actions/download-artifact@v4
+ with:
+ name: wheel
+ path: dist
+ - name: Install Dependencies
+ run: |
+ sudo apt-get update && sudo apt install --yes pandoc texlive-xetex librsvg2-bin
+ python -m pip install --upgrade pip
+ - name: Install rdmo[postgres] from wheel and start postgresql
+ run: |
+ python -m pip install "$(ls dist/*.whl)[ci,postgres]"
+ sudo systemctl start postgresql.service
+ pg_isready
+ sudo -u postgres psql --command="CREATE USER postgres_user PASSWORD 'postgres_password' CREATEDB"
+ - name: Prepare Env
+ run: |
+ cp -r testing/media testing/media_root && mkdir testing/log
- name: Install e2e tests dependencies
run: |
- npm install
- npm run build:prod
- playwright install chromium
- if: matrix.python-version == '3.12' && matrix.db-backend == 'postgres'
+ playwright install --with-deps chromium
- run: mkdir screenshots
+ - name: Collect static files into static root (only required if rdmo is installed from wheel)
+ run: python testing/manage.py collectstatic --noinput
- name: Run end-to-end tests
run: pytest -p randomly -p no:cacheprovider --reuse-db --numprocesses=auto --dist=loadscope -m e2e --nomigrations
- if: matrix.python-version == '3.12' && matrix.db-backend == 'postgres'
env:
DJANGO_DEBUG: True
GITHUB_DB_BACKEND: ${{ matrix.db-backend }}
@@ -113,7 +203,6 @@ jobs:
with:
name: screenshots
path: screenshots/*.png
- if: matrix.python-version == '3.12' && matrix.db-backend == 'postgres'
coveralls:
name: Indicate completion to coveralls
@@ -126,68 +215,6 @@ jobs:
with:
parallel-finished: true
- build-wheel:
- name: Build python wheel
- needs: test
- runs-on: ubuntu-24.04
- steps:
- - uses: actions/checkout@v4
- # update the version
- - name: Get short commit SHA
- run: |
- if [ "${{ github.event_name }}" = "pull_request" ]; then
- SHA="${{ github.event.pull_request.head.sha }}"
- else
- SHA="${{ github.sha }}"
- fi
- echo "SHA=$(git rev-parse --short $SHA)" >> $GITHUB_ENV
- - name: Get current version (MAJOR.MINOR.PATCH)
- id: current-version
- run: echo "current_version=$(grep -Po '(?<=__version__ = ")[\d\w.]+(?=")' rdmo/__init__.py)" >> $GITHUB_OUTPUT
- - name: Generate new version (current version + SHA)
- id: new-version
- run: echo "new_version=${{ steps.current-version.outputs.current_version }}+$SHA" >> $GITHUB_OUTPUT
- - name: Update version in rdmo/__init__.py
- run: |
- sed -i "s/__version__ = .*/__version__ = \"${{ steps.new-version.outputs.new_version }}\"/" rdmo/__init__.py
- # build the webpack bundle
- - uses: actions/setup-node@v4
- with:
- node-version: 18
- cache: npm
- - run: npm install && npm run build:prod
- # build the wheel
- - uses: actions/setup-python@v5
- with:
- python-version: '3.12'
- cache: pip
- - run: |
- python -m pip install --upgrade pip build[uv] twine
- pip --version
- - name: Build the wheel
- run: python -m build --installer=uv
- - name: Check the metadata of wheel and sdist
- run: python -m twine check --strict dist/*
- - name: Install package from built wheel
- run: python -m pip install --no-compile dist/rdmo*.whl # do not create __pycache__/*.pyc files
- - name: Write info to step summary
- run: |
- {
- echo -e "# ✓ Wheel successfully built (v${{ steps.new-version.outputs.new_version }})\n\n"
- echo 'Information about installed wheel
'
- echo -e "\n\`\`\`console"
- echo "$ python -m pip show --files --verbose rdmo"
- python -m pip show --files --verbose rdmo
- echo -e "\`\`\`\n "
- } >> $GITHUB_STEP_SUMMARY
- - name: Upload wheel as artifact
- uses: actions/upload-artifact@v4
- with:
- name: wheel
- path: dist/rdmo*.whl
- if-no-files-found: error
- retention-days: 30
-
dev-setup:
# Ref: structlog (MIT licensed)
name: "Test dev setup on ${{ matrix.os }}"
@@ -206,6 +233,7 @@ jobs:
dependencies:
name: Test installation of all dependencies
+ needs: build-wheel
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
@@ -213,12 +241,18 @@ jobs:
with:
python-version: "3.12"
cache: pip
+ - name: Download wheel
+ uses: actions/download-artifact@v4
+ with:
+ name: wheel
+ path: dist
- name: Install os requirements for python-ldap
- run: |
- sudo apt update
- sudo apt install --yes libldap2-dev libsasl2-dev
+ run: sudo apt-get update && sudo apt-get install --yes libldap2-dev libsasl2-dev
- run: python -m pip install --upgrade pip
- - run: python -m pip install .[allauth,ci,dev,gunicorn,ldap,mysql,postgres,pytest]
+ - name: Install rdmo wheel with all optional dependency groups
+ run: python -m pip install --no-compile "$(ls dist/*.whl)[allauth,ci,dev,gunicorn,ldap,mysql,postgres,pytest]"
+ - name: Verify installed packages have compatible dependencies
+ run: python -m pip check
- uses: actions/setup-node@v4
with:
node-version: 18
@@ -254,9 +288,10 @@ jobs:
if: always()
needs:
- lint
+ - build-wheel
- test
- coveralls
- - build-wheel
+ - test-e2e
- dev-setup
- dependencies
runs-on: ubuntu-24.04
diff --git a/rdmo/management/tests/conftest.py b/rdmo/management/tests/conftest.py
deleted file mode 100644
index 79cbc2d4aa..0000000000
--- a/rdmo/management/tests/conftest.py
+++ /dev/null
@@ -1,49 +0,0 @@
-import pytest
-
-from django.core.management import call_command
-
-from playwright.sync_api import BrowserType, Page, expect
-from pytest_django.live_server_helper import LiveServer
-
-from rdmo.accounts.utils import set_group_permissions
-
-
-@pytest.fixture
-def _e2e_tests_django_db_setup(django_db_setup, django_db_blocker, fixtures):
- """Set up database and populate with fixtures, that get restored for every test case."""
- with django_db_blocker.unblock():
- call_command("loaddata", *fixtures)
- set_group_permissions()
-
-
-
-@pytest.fixture
-def base_url_page(live_server: LiveServer, browser: BrowserType) -> Page:
- """Enable playwright to address URLs with base URL automatically prefixed."""
- context = browser.new_context(base_url=live_server.url)
- page = context.new_page()
- yield page
- context.close()
-
-
-# helper function for logging in the user
-def login_user(page: Page, username: str, password: str) -> Page:
- page.goto("/account/login")
- page.get_by_label("Username").fill(username, timeout=5000)
- page.get_by_label("Password").fill(password)
- page.get_by_role("button", name="Login").click()
- page.goto("/management")
- return page
-
-def logout_user(page: Page):
- page.goto("/account/logout")
- page.get_by_role("button", name="Logout").click()
- expect(page).to_have_url('/')
- return page
-
-@pytest.fixture
-def logged_in_user(_e2e_tests_django_db_setup, base_url_page, username:str, password: str) -> Page:
- """Log in as admin user through Django login UI, returns logged in page for e2e tests."""
- page = login_user(base_url_page, username, password)
- yield page
- logout_user(page)
diff --git a/rdmo/management/tests/e2e/__init__.py b/rdmo/management/tests/e2e/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/rdmo/management/tests/e2e/conftest.py b/rdmo/management/tests/e2e/conftest.py
new file mode 100644
index 0000000000..44d1321a2f
--- /dev/null
+++ b/rdmo/management/tests/e2e/conftest.py
@@ -0,0 +1,72 @@
+import os
+
+import pytest
+
+from django.conf import settings
+from django.contrib.auth import get_user_model
+from django.core.management import call_command
+from django.test import Client
+
+from playwright.sync_api import Page
+
+from rdmo.accounts.utils import set_group_permissions
+
+USERNAME = "editor" # the user needs exist in the database
+PLAYWRIGHT_TIMEOUT = 10_000 # timeout in ms
+
+
+@pytest.fixture(scope="session", autouse=True)
+def _set_django_allow_async_unsafe():
+ """pytest-playwright needs this setting to be enabled."""
+ os.environ.setdefault("DJANGO_ALLOW_ASYNC_UNSAFE", "true")
+
+
+@pytest.fixture
+def django_db_setup(django_db_setup, django_db_blocker, fixtures): # noqa: PT004 - pytest-django requires this name "django_db_setup"
+ """Set up database and populate with fixtures, that get restored for every test case.
+
+ This fixture overrides the django_db_setup in the main conftest.py, this only applies to the e2e tests
+ in this directory.
+ """
+ with django_db_blocker.unblock():
+ call_command("loaddata", *fixtures, verbosity=0)
+ set_group_permissions()
+
+
+@pytest.fixture
+def authenticated_client(db) -> Client:
+ """An authenticated test client, used to bypass the login page."""
+ user = get_user_model().objects.get(username=USERNAME)
+ client = Client()
+ client.user = user # attach user to client to access in other fixtures
+ client.force_login(user)
+ return client
+
+
+@pytest.fixture
+def page(live_server, browser, authenticated_client) -> Page:
+ """An authenticated playwright page.
+
+ The page is authenticated with session cookies from authenticated_client.
+ The page has access to the live server and starts at "/management".
+ The page has the authenticated user attached to it.
+ """
+
+ # retrieve the session cookie from the authenticated client
+ session_cookie = authenticated_client.cookies[settings.SESSION_COOKIE_NAME]
+ cookie = {
+ "name": session_cookie.key,
+ "value": session_cookie.value,
+ "url": live_server.url,
+ }
+ context = browser.new_context(base_url=live_server.url)
+ # the browser context is now "authenticated" with the session cookie
+ context.add_cookies([cookie])
+ page = context.new_page()
+ page.set_default_timeout(PLAYWRIGHT_TIMEOUT)
+ page.set_default_navigation_timeout(PLAYWRIGHT_TIMEOUT)
+ page.user = authenticated_client.user # attach user to page to access in tests
+ # the page starts at base_url + /management
+ page.goto("/management")
+ yield page
+ context.close()
diff --git a/rdmo/management/tests/test_frontend_import_options.py b/rdmo/management/tests/e2e/test_frontend_import_options.py
similarity index 76%
rename from rdmo/management/tests/test_frontend_import_options.py
rename to rdmo/management/tests/e2e/test_frontend_import_options.py
index 2cf980de61..b3f2dab3ba 100644
--- a/rdmo/management/tests/test_frontend_import_options.py
+++ b/rdmo/management/tests/e2e/test_frontend_import_options.py
@@ -1,46 +1,35 @@
# ruff: noqa: F811
-import os
-
import pytest
from playwright.sync_api import Page, expect
+from rdmo.management.tests.helpers_import_elements import IMPORT_ELEMENT_PANELS_LOCATOR
+from rdmo.management.tests.helpers_models import delete_all_objects
from rdmo.options.models import Option, OptionSet
-from .helpers_import_elements import IMPORT_ELEMENT_PANELS_LOCATOR
-from .helpers_models import delete_all_objects
-
pytestmark = pytest.mark.e2e
-# needed for playwright to run
-os.environ.setdefault("DJANGO_ALLOW_ASYNC_UNSAFE", "true")
-
-test_users = [('editor', 'editor')]
import_xml = "./testing/xml/elements/optionsets.xml"
import_xml_1 = "./testing/xml/elements/updated-and-changed/optionsets-1.xml"
-OPTIONSETS_COUNTS = {
- "total": 13,
- "updated": 13,
- "changed": 5,
- "warnings": 2
-}
-OPTIONSETS_COUNTS_HEADER_INFOS = [f"{k.capitalize()}: {v}" for k,v in OPTIONSETS_COUNTS.items()]
+OPTIONSETS_COUNTS = {"total": 13, "updated": 13, "changed": 5, "warnings": 2}
+OPTIONSETS_COUNTS_HEADER_INFOS = [f"{k.capitalize()}: {v}" for k, v in OPTIONSETS_COUNTS.items()]
# Defined in filterCheckBoxText in rdmo/management/assets/js/components/import/common/ImportFilters.js
IMPORT_FILTER_LABEL_TEXT = 'Show only new and changed elements (%s)'
-@pytest.mark.parametrize("username,password", test_users) # consumed by fixture
-def test_import_and_update_optionsets_in_management(logged_in_user: Page) -> None:
+
+def test_import_and_update_optionsets_in_management(page: Page) -> None:
"""Test that each content type is available through the navigation."""
delete_all_objects([OptionSet, Option])
- page = logged_in_user
expect(page.get_by_role("heading", name="Management")).to_be_visible()
expect(page.locator("strong").filter(has_text="Catalogs")).to_be_visible()
## 1. Import fresh optionset.xml
# choose the file to be imported
- page.locator("input[name=\"uploaded_file\"]").set_input_files(import_xml)
+ page.locator('input[name="uploaded_file"]').set_input_files(import_xml)
# click the import form submit button, this will take some time
- page.locator('#sidebar div.elements-sidebar form.upload-form.sidebar-form div.sidebar-form-button button.btn.btn-primary').click() # noqa: E501
+ page.locator(
+ "#sidebar div.elements-sidebar form.upload-form.sidebar-form div.sidebar-form-button button.btn.btn-primary"
+ ).click()
# wait for import to be finished with timeout 30s
expect(page.get_by_text("Import from: optionsets.xml")).to_be_visible(timeout=30_000)
## TODO test if ImportInfo numbers are correct
@@ -51,7 +40,7 @@ def test_import_and_update_optionsets_in_management(logged_in_user: Page) -> Non
page.get_by_role("link", name="Select all", exact=True).click()
page.get_by_role("link", name="Show all", exact=True).click()
rows_displayed_in_ui = page.locator(IMPORT_ELEMENT_PANELS_LOCATOR)
- expect(rows_displayed_in_ui).to_have_count(OPTIONSETS_COUNTS['total'])
+ expect(rows_displayed_in_ui).to_have_count(OPTIONSETS_COUNTS["total"])
# click the import button to start saving the instances to the db
page.get_by_role("button", name=f"Import {OPTIONSETS_COUNTS['total']} elements").click()
expect(page.get_by_role("heading", name="Import successful")).to_be_visible()
@@ -66,9 +55,11 @@ def test_import_and_update_optionsets_in_management(logged_in_user: Page) -> Non
## 2. import optionset-1.xml with changes
# choose the file to be imported
- page.locator("input[name=\"uploaded_file\"]").set_input_files(import_xml_1)
+ page.locator('input[name="uploaded_file"]').set_input_files(import_xml_1)
# click the import form submit button, this will take some time
- page.locator('#sidebar div.elements-sidebar form.upload-form.sidebar-form div.sidebar-form-button button.btn.btn-primary').click() # noqa: E501
+ page.locator(
+ "#sidebar div.elements-sidebar form.upload-form.sidebar-form div.sidebar-form-button button.btn.btn-primary"
+ ).click()
expect(page.get_by_text("Import from: optionsets-1.xml")).to_be_visible(timeout=40_000)
# assert changed elements
for text in OPTIONSETS_COUNTS_HEADER_INFOS:
diff --git a/rdmo/management/tests/test_frontend_import_questions.py b/rdmo/management/tests/e2e/test_frontend_import_questions.py
similarity index 75%
rename from rdmo/management/tests/test_frontend_import_questions.py
rename to rdmo/management/tests/e2e/test_frontend_import_questions.py
index 7b04e42489..3de152050c 100644
--- a/rdmo/management/tests/test_frontend_import_questions.py
+++ b/rdmo/management/tests/e2e/test_frontend_import_questions.py
@@ -1,36 +1,30 @@
# ruff: noqa: F811
-import os
-
import pytest
-from playwright.sync_api import Page, expect
+from playwright.sync_api import expect
+from rdmo.management.tests.helpers_import_elements import IMPORT_ELEMENT_PANELS_LOCATOR_SHOWN
+from rdmo.management.tests.helpers_models import delete_all_objects
from rdmo.questions.models import Catalog, Question, Section
from rdmo.questions.models import Page as PageModel
from rdmo.questions.models.questionset import QuestionSet
-from .helpers_import_elements import IMPORT_ELEMENT_PANELS_LOCATOR_SHOWN
-from .helpers_models import delete_all_objects
-
pytestmark = pytest.mark.e2e
-# needed for playwright to run
-os.environ.setdefault("DJANGO_ALLOW_ASYNC_UNSAFE", "true")
-test_users = [('editor', 'editor')]
-
-@pytest.mark.parametrize("username,password", test_users) # consumed by fixture
-def test_import_catalogs_in_management(logged_in_user: Page) -> None:
+def test_import_catalogs_in_management(page) -> None:
"""Test that the catalogs.xml can be imported correctly."""
+
delete_all_objects([Catalog, Section, PageModel, QuestionSet, Question])
- page = logged_in_user
expect(page.get_by_role("heading", name="Management")).to_be_visible()
expect(page.locator("strong").filter(has_text="Catalogs")).to_be_visible()
# choose the file to be imported
- page.locator("input[name=\"uploaded_file\"]").set_input_files("./testing/xml/elements/catalogs.xml")
+ page.locator('input[name="uploaded_file"]').set_input_files("./testing/xml/elements/catalogs.xml")
# click the import form submit button, this will take some time
- page.locator('#sidebar div.elements-sidebar form.upload-form.sidebar-form div.sidebar-form-button button.btn.btn-primary').click() # noqa: E501
+ page.locator(
+ "#sidebar div.elements-sidebar form.upload-form.sidebar-form div.sidebar-form-button button.btn.btn-primary"
+ ).click()
# wait for import to be finished with timeout 30s
expect(page.get_by_text("Import from: catalogs.xml")).to_be_visible(timeout=30_000)
## TODO test if ImportInfo numbers are correct
diff --git a/rdmo/management/tests/test_frontend_management_elements.py b/rdmo/management/tests/e2e/test_frontend_management_elements.py
similarity index 75%
rename from rdmo/management/tests/test_frontend_management_elements.py
rename to rdmo/management/tests/e2e/test_frontend_management_elements.py
index e735598e9c..47c51e9483 100644
--- a/rdmo/management/tests/test_frontend_management_elements.py
+++ b/rdmo/management/tests/e2e/test_frontend_management_elements.py
@@ -1,5 +1,4 @@
# ruff: noqa: F811
-import os
import re
from urllib.parse import urlparse
@@ -9,22 +8,15 @@
from rdmo.conditions.models import Condition
from rdmo.domain.models import Attribute
+from rdmo.management.tests.helpers_models import ModelHelper, model_helpers
from rdmo.questions.models import Catalog
-from .helpers_models import ModelHelper, model_helpers
-
pytestmark = pytest.mark.e2e
-# needed for playwright to run
-os.environ.setdefault("DJANGO_ALLOW_ASYNC_UNSAFE", "true")
-
-test_users = [('editor', 'editor')]
-@pytest.mark.parametrize("username,password", test_users)
@pytest.mark.parametrize("helper", model_helpers)
-def test_management_navigation(logged_in_user: Page, helper: ModelHelper, username: str, password: str) -> None:
+def test_management_navigation(page: Page, helper: ModelHelper) -> None:
"""Test that each content type is available through the navigation."""
- page = logged_in_user
expect(page.get_by_role("heading", name="Management")).to_be_visible()
# click a link in the navigation
@@ -43,25 +35,18 @@ def test_management_navigation(logged_in_user: Page, helper: ModelHelper, userna
page.screenshot(path="screenshots/management-navigation-catalog.png", full_page=True)
-
-@pytest.mark.parametrize("username,password", test_users)
@pytest.mark.parametrize("helper", model_helpers)
-def test_management_has_items(logged_in_user: Page, helper: ModelHelper) -> None:
+def test_management_has_items(page: Page, helper: ModelHelper) -> None:
"""Test all items in database are visible in management UI."""
- page = logged_in_user
num_items_in_database = helper.model.objects.count()
page.goto(f"/management/{helper.url}")
items_in_ui = page.locator(".list-group > .list-group-item")
expect(items_in_ui).to_have_count(num_items_in_database)
-@pytest.mark.parametrize("username,password", test_users)
@pytest.mark.parametrize("helper", model_helpers)
-def test_management_nested_view(
- logged_in_user: Page, helper: ModelHelper
-) -> None:
+def test_management_nested_view(page: Page, helper: ModelHelper) -> None:
"""For each element type, that has a nested view, click the first example."""
- page = logged_in_user
page.goto(f"/management/{helper.url}")
# Open nested view for element type
if helper.has_nested:
@@ -70,13 +55,9 @@ def test_management_nested_view(
expect(page.locator(".panel-default > .panel-body").first).to_be_visible()
-@pytest.mark.parametrize("username,password", test_users)
@pytest.mark.parametrize("helper", model_helpers)
-def test_management_create_model(
- logged_in_user: Page, helper: ModelHelper
-) -> None:
+def test_management_create_model(page: Page, helper: ModelHelper) -> None:
"""Test management UI can create objects in the database."""
- page = logged_in_user
num_objects_at_start = helper.model.objects.count()
page.goto(f"/management/{helper.url}")
# click "New" button
@@ -86,11 +67,7 @@ def test_management_create_model(
page.get_by_label(helper.form_field).fill(value)
if helper.model == Condition:
# conditions need to have a source attribute
- source_form = (
- page.locator(".form-group")
- .filter(has_text="Source")
- .locator(".select-item > .react-select")
- )
+ source_form = page.locator(".form-group").filter(has_text="Source").locator(".select-item > .react-select")
source_form.click()
page.keyboard.type(Attribute.objects.first().uri)
page.keyboard.press("Enter")
@@ -107,10 +84,8 @@ def test_management_create_model(
assert helper.model.objects.get(**query)
-@pytest.mark.parametrize("username,password", test_users)
@pytest.mark.parametrize("helper", model_helpers)
-def test_management_edit_model(logged_in_user: Page, helper: ModelHelper) -> None:
- page = logged_in_user
+def test_management_edit_model(page: Page, helper: ModelHelper) -> None:
page.goto(f"/management/{helper.url}")
# click edit
edit_button_title = f"Edit {helper.verbose_name}"
diff --git a/testing/manage.py b/testing/manage.py
new file mode 100644
index 0000000000..0004541852
--- /dev/null
+++ b/testing/manage.py
@@ -0,0 +1,11 @@
+#!/usr/bin/env python
+
+import os
+import sys
+
+if __name__ == "__main__":
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
+
+ from django.core.management import execute_from_command_line
+
+ execute_from_command_line(sys.argv)