From 7b5e389bd079b9c261a89f30fa4df84bd2a32633 Mon Sep 17 00:00:00 2001 From: Tatu Aalto Date: Sat, 4 Oct 2025 00:05:42 +0300 Subject: [PATCH 1/2] Refactor package_nodejs --- tasks.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks.py b/tasks.py index 68f81b0b9..33d22fd27 100644 --- a/tasks.py +++ b/tasks.py @@ -884,9 +884,9 @@ def package_nodejs(c: Context, architecture=None): _os_platform = _os_platform.replace("-", "_").replace(".", "_").replace(" ", "_") if _os_platform.startswith("macosx") and platform.machine().lower() == "x86_64": _os_platform = _os_platform.replace( - "universal2", platform.machine().lower().lower() + "universal2", platform.machine().lower() ) - if sysconfig.get_platform().lower() == "linux-x86_64": + elif sysconfig.get_platform().lower() == "linux-x86_64": _os_platform = f"manylinux_2_17_{architecture}" elif sysconfig.get_platform().lower() == "linux-aarch64": _os_platform = "manylinux_2_17_aarch64.manylinux2014_aarch64" From d3a84946bdb14900d0ee8ce70012453fbf464caa Mon Sep 17 00:00:00 2001 From: Tatu Aalto Date: Sat, 4 Oct 2025 00:17:44 +0300 Subject: [PATCH 2/2] Docker PR build --- .github/workflows/dockers.yml | 110 ------------------ .github/workflows/on-push.yml | 75 ++++++++++-- .github/workflows/on-release.yml | 99 ++++++++++++++++ .gitignore | 1 + .../chromiun_channel.robot | 2 + .../client_certificates.robot | 2 + .../01_Browser_Management/geolocation.robot | 3 + .../playwright_state.robot | 4 +- .../basic_getters_expect_errors.robot | 2 +- atest/test/02_Content_Keywords/cookie.robot | 8 +- atest/test/02_Content_Keywords/dialogs.robot | 8 -- atest/test/02_Content_Keywords/files.robot | 2 + .../02_Content_Keywords/readme_example.robot | 2 +- .../test_record_selector.robot | 2 +- atest/test/03_Waiting/wait_for_http.robot | 2 + .../test/05_JS_Tests/http_with_waiting.robot | 1 + atest/test/05_JS_Tests/jsextension_list.robot | 5 +- .../05_JS_Tests/local_session_storage.robot | 2 + .../06_Examples/open_in_another_tab.robot | 3 +- atest/test/06_Examples/presenter_mode.robot | 2 +- .../Import_JS_and_JS_in_Python.robot | 7 +- atest/test/09_Plugins/plugin.robot | 1 + .../network_idle_file.robot | 2 +- .../network_idle_test.robot | 4 +- atest/test/12_rfbrowser/translation.robot | 1 + docker/Dockerfile.dev_pr | 51 ++++++++ docker/README.md | 18 ++- tasks.py | 32 ++++- 28 files changed, 308 insertions(+), 143 deletions(-) delete mode 100644 .github/workflows/dockers.yml create mode 100644 docker/Dockerfile.dev_pr diff --git a/.github/workflows/dockers.yml b/.github/workflows/dockers.yml deleted file mode 100644 index 0654cc853..000000000 --- a/.github/workflows/dockers.yml +++ /dev/null @@ -1,110 +0,0 @@ -name: Docker image and tests - -on: - push: - release: - types: [ published ] - workflow_dispatch: - - -jobs: - docker-image: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v5 - - name: Set up QEMU for cross-platforms builds - uses: docker/setup-qemu-action@v3 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Login to Docker Hub - if: github.event_name != 'push' - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_TOKEN }} - - - name: Docker meta - id: meta - uses: docker/metadata-action@v5 - with: - images: marketsquare/robotframework-browser - tags: | - type=ref,event=branch - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=semver,pattern={{major}} - flavor: | - latest=true - - - name: Push tag :version_number to Docker Hub - uses: docker/build-push-action@v6 - with: - tags: ${{ steps.meta.outputs.tags }} - file: docker/Dockerfile.latest_release - platforms: linux/arm64/v8,linux/amd64 - push: ${{ github.event_name != 'push' }} - - - name: Docker meta - id: meta_github - uses: docker/metadata-action@v5 - with: - images: ghcr.io/marketsquare/robotframework-browser/rfbrowser-stable - tags: | - type=ref,event=branch - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=semver,pattern={{major}} - flavor: | - latest=true - - - name: Login to GitHub Container Registry - if: github.event_name != 'push' - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Push to GitHub Packages - uses: docker/build-push-action@v6 - with: - platforms: linux/arm64/v8,linux/amd64 - file: docker/Dockerfile.latest_release - tags: ${{ steps.meta_github.outputs.tags }} - push: ${{ github.event_name != 'push' }} - - test-docker-image: - needs: docker-image - runs-on: ubuntu-latest - if: github.event_name != 'push' - steps: - - uses: actions/checkout@v5 - - name: Set up Python 3.11 - uses: actions/setup-python@v6 - with: - python-version: 3.11 - cache: 'pip' - - name: Install python dependencies - run: | - python -m pip install --upgrade pip - pip install uv - uv pip install wheel --python 3.11 --system - uv pip install -r Browser/dev-requirements.txt --python 3.11 --system - - name: Install invoke deps - run: | - invoke deps - - name: build testing docker image - run: | - invoke docker-tester - - name: set permissions - run: chmod -R 777 atest/ - - name: Run tests with latest stable docker image - # continue on error until all docker tests pass - run: | - invoke docker-test - - uses: actions/upload-artifact@v4 - if: ${{ always() }} - with: - name: ${{ matrix.os }} ${{ matrix.python-version }} Clean install results - path: atest/output diff --git a/.github/workflows/on-push.yml b/.github/workflows/on-push.yml index 7ec018734..90b76172a 100644 --- a/.github/workflows/on-push.yml +++ b/.github/workflows/on-push.yml @@ -354,7 +354,7 @@ jobs: inv demo-app - uses: actions/upload-artifact@v4 with: - name: demoapp--bb-test-${{ matrix.os }} + name: demoapp-bb-test-${{ matrix.os }} path: zip_results/demoapp if-no-files-found: error - name: Create Distributable BrowserBatteries Package @@ -389,22 +389,22 @@ jobs: uses: actions/setup-node@v6 with: node-version: "22.x" - - name: Download rfbrowser-wheel for BrowserBatteries tests + - name: Download browser-wheel uses: actions/download-artifact@v5 with: name: rfbrowser-wheel-bb-test path: rfbrowser-wheel - - name: Download BrowserBatteries wheels + - name: Download BrowserBatteries wheel uses: actions/download-artifact@v5 with: name: browser-batteries-wheels-bb-test-${{ matrix.os }} path: browser-batteries-wheels - - name: Download demoapp wheels + - name: Download demoapp uses: actions/download-artifact@v5 with: - name: demoapp--bb-test-${{ matrix.os }} + name: demoapp-bb-test-${{ matrix.os }} path: demoapp - - name: Install Browser and BrowserBatteries on ${{ matrix.os }} + - name: Install Browser and BrowserBatteries run: | python -m pip install --upgrade pip pip install rfbrowser-wheel/robotframework_browser-*-py3-none-any.whl @@ -422,7 +422,7 @@ jobs: ls -l demoapp unzip demoapp/demo-app*.zip -d . - name: Run tests on Linux with packed demoapp - if : matrix.os == 'ubuntu-latest' || matrix.os == 'ubuntu-24.04-arm' + if: matrix.os == 'ubuntu-latest' || matrix.os == 'ubuntu-24.04-arm' run: | xvfb-run --auto-servernum invoke atest-robot --smoke - name: Run tests on MacOS with packed demoapp @@ -440,3 +440,64 @@ jobs: python -m GHAReports --robotlog atest/output/output.xml python -m GHAReports --robotlog atest/output/output.xml --markdown fail.md --no-totals --no-passes --no-skipped --fails --no-warnings cat fail.md + + docker_image: + runs-on: ubuntu-latest + needs: build_browser_batteries_wheels + permissions: write-all + steps: + - uses: actions/checkout@v5 + - uses: actions/setup-python@v6 + with: + python-version: "3.14" + cache: 'pip' + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/marketsquare/robotframework-browser/rfbrowser + tags: | + type=raw,value=tidii + - name: Download browser wheel + uses: actions/download-artifact@v5 + with: + name: rfbrowser-wheel-bb-test + path: docker/dist + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Build with GitHub Packages + uses: docker/build-push-action@v6 + with: + context: . + file: docker/Dockerfile.dev_pr + tags: tidii + labels: ${{ steps.meta.outputs.labels }} + push: false + - name: Download demo app + uses: actions/download-artifact@v5 + with: + name: demoapp-bb-test-ubuntu-latest + path: demoapp + - name: unzip demo app + run: | + rm -rf node + ls -l demoapp + unzip demoapp/demo-app*.zip -d . + ls -l node + - name: Start demo app and run tests with docker image + run: | + pip install uv + uv pip install invoke robotframework-ghareports --python 3.14 --system + invoke run-test-app-no-build --asynchronous + docker run -v ./atest/:/home/pwuser/test -t tidii:latest bash -c "robot -v SERVER:172.17.0.1:7272 --exclude no-docker-pr -L debug --outputdir /home/pwuser/output /home/pwuser/test" + inv docker-copy-output + - name: Github Job Summary + if: ${{ always() }} + run: | + python -m GHAReports --robotlog output_docker/output.xml + python -m GHAReports --robotlog output_docker/output.xml --markdown fail.md --no-totals --no-passes --no-skipped --fails --no-warnings + cat fail.md \ No newline at end of file diff --git a/.github/workflows/on-release.yml b/.github/workflows/on-release.yml index c51c78acc..60833c362 100644 --- a/.github/workflows/on-release.yml +++ b/.github/workflows/on-release.yml @@ -266,3 +266,102 @@ jobs: twine check dist/* - name: Publish BrowserBatteries distribution to PyPI uses: pypa/gh-action-pypi-publish@release/v1 + + docker-image: + needs: publish-browser-to-pypi + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - name: Set up QEMU for cross-platforms builds + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: marketsquare/robotframework-browser + tags: | + type=ref,event=branch + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + flavor: | + latest=true + + - name: Push tag :version_number to Docker Hub + uses: docker/build-push-action@v6 + with: + tags: ${{ steps.meta.outputs.tags }} + file: docker/Dockerfile.latest_release + platforms: linux/arm64/v8,linux/amd64 + push: ${{ github.event_name != 'push' }} + + - name: Docker meta + id: meta_github + uses: docker/metadata-action@v5 + with: + images: ghcr.io/marketsquare/robotframework-browser/rfbrowser-stable + tags: | + type=ref,event=branch + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + flavor: | + latest=true + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Push to GitHub Packages + uses: docker/build-push-action@v6 + with: + platforms: linux/arm64/v8,linux/amd64 + file: docker/Dockerfile.latest_release + tags: ${{ steps.meta_github.outputs.tags }} + push: ${{ github.event_name != 'push' }} + + test-docker-image: + needs: docker-image + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - name: Set up Python 3.11 + uses: actions/setup-python@v6 + with: + python-version: 3.11 + cache: 'pip' + - name: Install python dependencies + run: | + python -m pip install --upgrade pip + pip install uv + uv pip install wheel --python 3.11 --system + uv pip install -r Browser/dev-requirements.txt --python 3.11 --system + - name: Install invoke deps + run: | + invoke deps + - name: build testing docker image + run: | + invoke docker-tester + - name: set permissions + run: chmod -R 777 atest/ + - name: Run tests with latest stable docker image + # continue on error until all docker tests pass + run: | + invoke docker-test + - uses: actions/upload-artifact@v4 + if: ${{ always() }} + with: + name: Docker test results + path: atest/output diff --git a/.gitignore b/.gitignore index dcc13c558..6509a68ae 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ __pycache__ robotframework_browser.egg-info/ .venv zip_results +mypy_stub # utest utest/output diff --git a/atest/test/01_Browser_Management/chromiun_channel.robot b/atest/test/01_Browser_Management/chromiun_channel.robot index 7d5bf6807..d74368631 100644 --- a/atest/test/01_Browser_Management/chromiun_channel.robot +++ b/atest/test/01_Browser_Management/chromiun_channel.robot @@ -3,6 +3,8 @@ Resource imports.resource Suite Teardown Close Browser ALL +Test Tags no-docker-pr + *** Test Cases *** Wrong Browser With Channel Run Keyword And Expect Error diff --git a/atest/test/01_Browser_Management/client_certificates.robot b/atest/test/01_Browser_Management/client_certificates.robot index 6c5fd863a..647a9886b 100644 --- a/atest/test/01_Browser_Management/client_certificates.robot +++ b/atest/test/01_Browser_Management/client_certificates.robot @@ -6,6 +6,8 @@ Suite Setup Setup Suite Teardown Suite Teardown Test Teardown Close Browser ALL +Test Tags no-docker-pr + *** Test Cases *** Open Browser With Client Certificate New Browser browser=${BROWSER} headless=${HEADLESS} diff --git a/atest/test/01_Browser_Management/geolocation.robot b/atest/test/01_Browser_Management/geolocation.robot index f550c2b3e..450306129 100644 --- a/atest/test/01_Browser_Management/geolocation.robot +++ b/atest/test/01_Browser_Management/geolocation.robot @@ -21,15 +21,18 @@ Force Tags no-iframe *** Test Cases *** Set Geolocation On Browser Startup + [Tags] no-docker-pr Start Context With Geolocation Check Geolocation 42 -42.42 Set Geolocation + [Tags] no-docker-pr [Setup] Start Context With Geolocation Set Geolocation 72.56 145.89 0.23 Check Geolocation 72.56 145.89 Enable Geolocation + [Tags] no-docker-pr [Setup] Start Context Without Geolocation Set Browser Timeout timeout=500ms scope=Test Set Geolocation 11.11 22.22 33.33 diff --git a/atest/test/01_Browser_Management/playwright_state.robot b/atest/test/01_Browser_Management/playwright_state.robot index d4869f3c5..766cbfde4 100644 --- a/atest/test/01_Browser_Management/playwright_state.robot +++ b/atest/test/01_Browser_Management/playwright_state.robot @@ -28,7 +28,7 @@ New Context Does Not Open A Page Should Be Equal ${no_page_id} NO PAGE OPEN Open Browser Opens Everything - [Tags] slow + [Tags] slow no-docker-pr ${old_timeout} = Set Browser Timeout 30 seconds Open Browser url=${FORM_URL} Get Title == prefilled_email_form.html @@ -262,6 +262,7 @@ New Context With DefaultBrowserType Ff Set Browser Timeout ${old_timeout} New Context With baseURL + [Tags] no-docker-pr New Context baseURL=${ROOT_URL} New Page dist/#/ Get Url == ${LOGIN_URL} @@ -440,6 +441,7 @@ Launch Browser Server Generated wsEndpoint [Teardown] Close Browser Server ${wsEndpoint} Launch Browser Server Via CLI + [Tags] no-docker-pr ${python} = Get Python Binary Path ${process1} = Start Process ... ${python} diff --git a/atest/test/02_Content_Keywords/basic_getters_expect_errors.robot b/atest/test/02_Content_Keywords/basic_getters_expect_errors.robot index d187ed8da..95669a9a6 100644 --- a/atest/test/02_Content_Keywords/basic_getters_expect_errors.robot +++ b/atest/test/02_Content_Keywords/basic_getters_expect_errors.robot @@ -164,7 +164,7 @@ Get Viewport Size Custom Error ... Get Viewport Size all == ${expected} My error {expected_type} Get Url Default Error - [Tags] expect_error + [Tags] expect_error no-docker-pr Run Keyword And Expect Error ... URL 'http://localhost:*' (str) should contain 'Valid' (str) ... Get Url contains Valid diff --git a/atest/test/02_Content_Keywords/cookie.robot b/atest/test/02_Content_Keywords/cookie.robot index c9d24addc..4fdf31486 100644 --- a/atest/test/02_Content_Keywords/cookie.robot +++ b/atest/test/02_Content_Keywords/cookie.robot @@ -29,7 +29,7 @@ Add Cookie Without Url, Path And Domain ... Add Cookie Foo Bar Add Cookie With Url - [Tags] no-windows-support + [Tags] no-windows-support no-docker-pr ${url} = Get Url Add Cookie Foo Bar url=${url} ${cookies} = Get Cookies @@ -37,7 +37,7 @@ Add Cookie With Url Should Be Equal ${cookies}[0][path] / Add Cookie With Domain And Path - [Tags] no-windows-support + [Tags] no-windows-support no-docker-pr ${url} = Get Url ${parsed_url} = Common.Parse Url ${url} Add Cookie Foo Bar domain=${parsed_url.netloc} path=${parsed_url.path} @@ -58,6 +58,7 @@ Add Cookie With URL And Domain Should Fail ... path=${parsed_url.path} Add Cookie With All Settings + [Tags] no-docker-pr ${url} = Get Url ${date_string} = Get Current Date increment=1 day Add Cookie @@ -96,6 +97,7 @@ Add Cookie With All Settings As String Should Contain ${cookies} Tidii=Kala; Foo=Bar Add Cookie With Expiry As Epoch String + [Tags] no-docker-pr ${url} = Get Url ${epoch} = Get Current Date increment=1 day result_format=epoch ${date_time} = Convert Date ${epoch} @@ -114,6 +116,7 @@ Add Cookie With Expiry As Epoch String Should Be Equal ${expires.year} ${expires.year} Add Cookie With Expiry As Epoch Int + [Tags] no-docker-pr ${url} = Get Url ${epoch} = Get Current Date increment=1 day result_format=epoch Add Cookie @@ -149,6 +152,7 @@ Add Cookie With Expiry As Epoch In Different Format Should Match Regexp ${epoch_as_str} \\d\\d\\d\\d-\\d\\d-\\d\\d \\d\\d\\:\\d\\d\\:\\d\\d Add Cookie With Expiry As Datetime Object + [Tags] no-docker-pr ${url} = Get Url ${datetime} = Evaluate datetime.datetime.now() + datetime.timedelta(hours=1) # local time Add Cookie diff --git a/atest/test/02_Content_Keywords/dialogs.robot b/atest/test/02_Content_Keywords/dialogs.robot index 406dc8791..898715c21 100644 --- a/atest/test/02_Content_Keywords/dialogs.robot +++ b/atest/test/02_Content_Keywords/dialogs.robot @@ -12,14 +12,6 @@ Accept Alert Handle Future Dialogs action=accept Click \#alerts -Clicking Through Alert Fails - [Tags] not-implemented - # The new close page / context / browser gets broken by this? - Run Keyword And Expect Error - ... Could not find element with selector `#alerts` within timeout. - ... Click - ... \#alerts - Promptinput Works Handle Future Dialogs action=accept prompt_input=Some Input String Click \#prompts diff --git a/atest/test/02_Content_Keywords/files.robot b/atest/test/02_Content_Keywords/files.robot index 9653355a1..1ff56eca2 100644 --- a/atest/test/02_Content_Keywords/files.robot +++ b/atest/test/02_Content_Keywords/files.robot @@ -93,11 +93,13 @@ Invalid Upload Path ... Upload File By Selector \#file_chooser NonExistentFile Relative Upload Path + [Tags] no-docker-pr New Page ${LOGIN_URL} File Should Exist atest${/}test${/}02_Content_Keywords${/}test_upload_file Upload File By Selector \#file_chooser atest${/}test${/}02_Content_Keywords${/}test_upload_file Relative Upload Path With Promise + [Tags] no-docker-pr File Should Exist atest${/}test${/}..${/}test${/}02_Content_Keywords${/}test_upload_file Upload With Promise atest${/}test${/}..${/}test${/}02_Content_Keywords${/}test_upload_file diff --git a/atest/test/02_Content_Keywords/readme_example.robot b/atest/test/02_Content_Keywords/readme_example.robot index 6bfefb3bc..a06e75f8c 100644 --- a/atest/test/02_Content_Keywords/readme_example.robot +++ b/atest/test/02_Content_Keywords/readme_example.robot @@ -3,7 +3,7 @@ Resource imports.resource Suite Teardown Close Page -Force Tags no-iframe need-inet +Test Tags no-iframe need-inet no-docker-pr *** Test Cases *** Example diff --git a/atest/test/02_Content_Keywords/test_record_selector.robot b/atest/test/02_Content_Keywords/test_record_selector.robot index dce377220..74aaae7a1 100644 --- a/atest/test/02_Content_Keywords/test_record_selector.robot +++ b/atest/test/02_Content_Keywords/test_record_selector.robot @@ -6,7 +6,7 @@ Suite Teardown Close Browser *** Test Cases *** Finds A Selector - [Tags] no-mac-support slow + [Tags] no-mac-support slow no-docker-pr [Timeout] 2 minutes New Page ${LOGIN_URL} ${recording} = Promise To record selector diff --git a/atest/test/03_Waiting/wait_for_http.robot b/atest/test/03_Waiting/wait_for_http.robot index 9e3d6ccfc..c6600eb12 100644 --- a/atest/test/03_Waiting/wait_for_http.robot +++ b/atest/test/03_Waiting/wait_for_http.robot @@ -27,6 +27,7 @@ Wait For Request Url Wait For Request matcher=${ROOT_URL}api/get/json timeout=1s Wait For Request Regex + [Tags] no-docker-pr Click \#delayed_request Wait For Request matcher=/\\/\\/local\\w+\\:\\d+\\/api/ timeout=1s @@ -76,6 +77,7 @@ Wait For Response Synchronous With Default Timeout Wait For Response Wait For Response Synchronous With Regex Matcher + [Tags] no-docker-pr Click \#delayed_request Wait For Response matcher=/\\/\\/local\\w+\\:\\d+\\/api/ diff --git a/atest/test/05_JS_Tests/http_with_waiting.robot b/atest/test/05_JS_Tests/http_with_waiting.robot index 4e9053106..9081eb324 100644 --- a/atest/test/05_JS_Tests/http_with_waiting.robot +++ b/atest/test/05_JS_Tests/http_with_waiting.robot @@ -28,6 +28,7 @@ POST With Waiting Json Response Should Be Equal ${content}[request][postData][name] George GET With Text Response + [Tags] no-docker-pr ${promise} = Promise To Wait For Response matcher=/http://\\w+:\\d+/api/get/text/i timeout=3s &{response} = HTTP /api/get/text ${content} = Wait For ${promise} diff --git a/atest/test/05_JS_Tests/jsextension_list.robot b/atest/test/05_JS_Tests/jsextension_list.robot index df6cd7ec3..2ca46b8d4 100644 --- a/atest/test/05_JS_Tests/jsextension_list.robot +++ b/atest/test/05_JS_Tests/jsextension_list.robot @@ -37,7 +37,7 @@ Calling Custom Js Keyword With Default Value Should Be Equal ${val3} EVEN Connecting And Creating A Remote Browser - [Tags] slow + [Tags] slow no-docker-pr ${wsEndpoint} = Create Remote Browser ${browser} = Connect To Browser ${wsEndpoint} Should Not Be Equal ${browser} ${NULL} @@ -46,6 +46,7 @@ Connecting And Creating A Remote Browser [Teardown] Close Remote Clean Defaults In The Keyword From Python To JS And Back + [Tags] no-docker-pr ${result} = MoreDefaults Should Be Equal ${result}[bTrue] ${TRUE} Should Be Equal ${result}[bFalse] ${FALSE} @@ -70,6 +71,7 @@ Defaults In The Keyword From Python To JS And Back Should Be Equal ${result8}[undefineder] ${NONE} Crashing Keyword + [Tags] no-docker-pr Run Keyword And Expect Error Error: Crash CrashKeyword Failing Import @@ -77,6 +79,7 @@ Failing Import ... jsextension=${CURDIR}/wrong.js List Imports + [Tags] no-docker-pr ${r} = My Other Keyword test Should Be Equal ${r} test diff --git a/atest/test/05_JS_Tests/local_session_storage.robot b/atest/test/05_JS_Tests/local_session_storage.robot index 3ae211f23..3d9dea33a 100644 --- a/atest/test/05_JS_Tests/local_session_storage.robot +++ b/atest/test/05_JS_Tests/local_session_storage.robot @@ -44,6 +44,7 @@ Sessionstorage Clear 2 SessionStorage Get Item key2 == ${None} LocalStorage In Frame + [Tags] no-docker-pr [Setup] New Page http://localhost:${SERVER_PORT}/framing.html?url=http://127.0.0.1:${SERVER_PORT}/prefilled_email_form.html LocalStorage Set Item key value_of_main_page LocalStorage Set Item key_two value_of_main_page_two @@ -61,6 +62,7 @@ LocalStorage In Frame LocalStorage Get Item key == value_of_main_page SessionStorage In Frame + [Tags] no-docker-pr [Setup] New Page http://localhost:${SERVER_PORT}/framing.html?url=http://127.0.0.1:${SERVER_PORT}/prefilled_email_form.html SessionStorage Set Item key value_of_main_page_session SessionStorage Set Item key_two value_of_main_page_session_two diff --git a/atest/test/06_Examples/open_in_another_tab.robot b/atest/test/06_Examples/open_in_another_tab.robot index 56bffc967..3a64fc9b8 100644 --- a/atest/test/06_Examples/open_in_another_tab.robot +++ b/atest/test/06_Examples/open_in_another_tab.robot @@ -5,10 +5,11 @@ Resource imports.resource Test Setup Open Browser To No Page Test Teardown Close Browser -Force Tags slow +Test Tags slow *** Test Cases *** Open PDF In Another Tab And Download It + [Tags] no-docker-pr [Setup] New Browser headless=${FALSE} downloadsPath=${EXECDIR} New Context acceptDownloads=${TRUE} Set Browser Timeout 30s diff --git a/atest/test/06_Examples/presenter_mode.robot b/atest/test/06_Examples/presenter_mode.robot index 3ce19500a..1b7cfcdd4 100644 --- a/atest/test/06_Examples/presenter_mode.robot +++ b/atest/test/06_Examples/presenter_mode.robot @@ -6,7 +6,7 @@ Library ../../library/presenter_mode.py Suite Setup New Browser headless=False Suite Teardown Close Browser -Force Tags slow no-iframe +Test Tags slow no-iframe no-docker-pr *** Test Cases *** Filling The Text With True diff --git a/atest/test/09_Plugins/Import_JS_and_JS_in_Python.robot b/atest/test/09_Plugins/Import_JS_and_JS_in_Python.robot index 98ea6e202..7e9693777 100644 --- a/atest/test/09_Plugins/Import_JS_and_JS_in_Python.robot +++ b/atest/test/09_Plugins/Import_JS_and_JS_in_Python.robot @@ -11,7 +11,7 @@ Library Browser Suite Setup New Browser ${BROWSER} headless=${HEADLESS} Test Teardown Close Context ALL -Force Tags no-iframe +Test Tags no-iframe *** Test Cases *** Calling Custom Js Keyword @@ -36,7 +36,7 @@ Calling Custom Js Keyword With Default Value Should Be Equal ${val3} EVEN Connecting And Creating A Remote Browser - [Tags] slow + [Tags] slow no-docker-pr ${wsEndpoint} = Create Remote Browser ${browser} = Connect To Browser ${wsEndpoint} Should Not Be Equal ${browser} ${NULL} @@ -45,6 +45,7 @@ Connecting And Creating A Remote Browser [Teardown] Close Remote Clean Defaults In The Keyword From Python To JS And Back + [Tags] no-docker-pr ${result} = MoreDefaults Should Be Equal ${result}[bTrue] ${TRUE} Should Be Equal ${result}[bFalse] ${FALSE} @@ -69,6 +70,7 @@ Defaults In The Keyword From Python To JS And Back Should Be Equal ${result8}[undefineder] ${NONE} Crashing Keyword + [Tags] no-docker-pr Run Keyword And Expect Error Error: Crash CrashKeyword Failing Import @@ -108,6 +110,7 @@ Test Js Plugin Called From Python Plugin Get Scroll Position ${None} left == 30 Pluging Keyword Example Location + [Tags] no-docker-pr [Setup] New Page ${FORM_URL} ${location} = Get Location Object ${url} = Get Url diff --git a/atest/test/09_Plugins/plugin.robot b/atest/test/09_Plugins/plugin.robot index 2091179d7..b59273540 100644 --- a/atest/test/09_Plugins/plugin.robot +++ b/atest/test/09_Plugins/plugin.robot @@ -47,6 +47,7 @@ Test Js Plugin Called From Python Plugin Get Scroll Position ${None} left == 30 Pluging Keyword Example Location + [Tags] no-docker-pr [Setup] New Page ${FORM_URL} ${location} = Get Location Object ${url} = Get Url diff --git a/atest/test/11_tidy_transformer/network_idle_file.robot b/atest/test/11_tidy_transformer/network_idle_file.robot index 456c7238b..5d0c223e4 100644 --- a/atest/test/11_tidy_transformer/network_idle_file.robot +++ b/atest/test/11_tidy_transformer/network_idle_file.robot @@ -1,5 +1,5 @@ *** Settings *** -Test Tags tidy-transformer +Test Tags tidy-transformer no-docker-pr *** Test Cases *** Parsing Wait Until Network Is Idle To Wait For Load State diff --git a/atest/test/11_tidy_transformer/network_idle_test.robot b/atest/test/11_tidy_transformer/network_idle_test.robot index a05ebcf78..13cd7660b 100644 --- a/atest/test/11_tidy_transformer/network_idle_test.robot +++ b/atest/test/11_tidy_transformer/network_idle_test.robot @@ -1,5 +1,7 @@ *** Settings *** -Resource imports.resource +Resource imports.resource + +Test Tags no-docker-pr *** Test Cases *** Tranform Wait Until Network Is Idle Keyword diff --git a/atest/test/12_rfbrowser/translation.robot b/atest/test/12_rfbrowser/translation.robot index e38912785..641d095e8 100644 --- a/atest/test/12_rfbrowser/translation.robot +++ b/atest/test/12_rfbrowser/translation.robot @@ -33,6 +33,7 @@ Create Translation File With Python Plugin [Teardown] Remove File ${OUTPUT_DIR}/translation.json Create Translation File With JS Plugin + [Tags] no-docker-pr ${entry_cmd} = Get Enty Command ${process} = Run Process ... ${entry_cmd} translation ${OUTPUT_DIR}/translation.json --plugings ${CURDIR}/SomePlugin.py --jsextension ${CURDIR}/jsplugin.js diff --git a/docker/Dockerfile.dev_pr b/docker/Dockerfile.dev_pr new file mode 100644 index 000000000..08757a0ad --- /dev/null +++ b/docker/Dockerfile.dev_pr @@ -0,0 +1,51 @@ +FROM mcr.microsoft.com/playwright:v1.56.0-noble + +# Update apt-get +USER root +RUN apt-get update +RUN python3 --version +RUN apt install -y python3-pip python3.12-venv + +# Clean up +USER root +RUN apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Set environment variables +ENV PATH="/home/pwuser/.local/bin:${PATH}" +ENV NODE_PATH=/usr/lib/node_modules + +# Cache operations +USER root +RUN mv /root/.cache/ /home/pwuser/.cache || true +RUN chmod a+rwx -R /home/pwuser/.cache || true + +# Switch to pwuser for the remaining operations +USER pwuser + +# Create venv and active it +RUN python3 -m venv /home/pwuser/.venv +ENV PATH="/home/pwuser/.venv/bin:$PATH" + +# Upgrade pip and wheel for the user +RUN pip3 install --no-cache-dir --upgrade pip wheel uv + +# Copy the dist files +COPY docker/dist/*.whl /home/pwuser/ +# Install RobotFramework and Browser library +RUN uv pip install --no-cache-dir --upgrade robotframework && \ + uv pip install --no-cache-dir /home/pwuser/robotframework_browser-*.whl && \ + rm /home/pwuser/*.whl + +# Initialize Browser library without browsers binaries +RUN rfbrowser init --skip-browsers + +# Install development dependencies +RUN uv pip install --no-cache-dir --upgrade \ + robotframework-pabot \ + robotstatuschecker \ + Pillow \ + python-dateutil \ + robotframework-crypto \ + robotframework-archivelibrary \ + cryptography diff --git a/docker/README.md b/docker/README.md index f54930401..a12d3718a 100644 --- a/docker/README.md +++ b/docker/README.md @@ -43,10 +43,26 @@ docker build --no-cache -t tidii --file Dockerfile.latest_release . > out.txt 2> Run test with locally build image ```bash -docker run -v ./atest/:/test -t tidii:latest bash -c "robot --outputdir /test/output /test" +docker run -v ./atest/:/home/pwuser/test -t tidii:latest bash -c "robot --outputdir /test/output /home/pwuser/test" ```` To start bash in container ```bash docker run -i -t tidii:latest bash ``` + +# Run docker pr build test + +1. Modify [Dockerfile.dev_pr](Dockerfile.dev_pr) +> COPY docker/dist/*.whl /home/pwuser/ + +to +> COPY dist/*.whl /home/pwuser/ +2. Build Browser wheel with: `invoke package` +3. Build Docker pr container +> docker build -t tidii --file docker/Dockerfile.dev_pr . + +4. Run test with command below: +```bash +docker run -v ./atest/:/home/pwuser/test -t tidii:latest bash -c "robot -v SERVER:host.docker.internal:7272 --exclude no-docker-pr -L debug --outputdir /home/pwuser/output /home/pwuser/test" +``` diff --git a/tasks.py b/tasks.py index 33d22fd27..41fec52dd 100644 --- a/tasks.py +++ b/tasks.py @@ -6,6 +6,7 @@ import subprocess import sys import sysconfig +import time import traceback import zipfile from collections.abc import Iterable @@ -794,10 +795,35 @@ def docker_run_tmp_tests(c): @task(build) -def run_test_app(c): +def run_test_app(c: Context): + """Run dynamic test app.""" c.run("node node/dynamic-test-app/dist/server.js") +@task +def run_test_app_no_build(c: Context, asynchronous=False): + """Run dynamic test app without building. + + Args: + asynchronous: When true, returns immediately after starting the subprocess. + """ + print("Running test app without building.") + c.run("node node/dynamic-test-app/dist/server.js", asynchronous=asynchronous) + time.sleep(4) + print(f"Test app started with asynchronous mode {asynchronous}.") + + +@task +def docker_copy_output(c: Context): + """Copy atest output from docker container to host.""" + output = ROOT_DIR / "docker_last_container.txt" + output.unlink(missing_ok=True) + c.run(f"docker ps --all --last 1 --format '{{{{.ID}}}}' > {output}") + with output.open("r") as file: + container_id = file.read().strip() + c.run(f"docker cp {container_id}:/home/pwuser/output ./output_docker") + + @task def docs(c, version=None): """Generate library keyword documentation. @@ -883,9 +909,7 @@ def package_nodejs(c: Context, architecture=None): print(f"Current os platform: {_os_platform}") _os_platform = _os_platform.replace("-", "_").replace(".", "_").replace(" ", "_") if _os_platform.startswith("macosx") and platform.machine().lower() == "x86_64": - _os_platform = _os_platform.replace( - "universal2", platform.machine().lower() - ) + _os_platform = _os_platform.replace("universal2", platform.machine().lower()) elif sysconfig.get_platform().lower() == "linux-x86_64": _os_platform = f"manylinux_2_17_{architecture}" elif sysconfig.get_platform().lower() == "linux-aarch64":