From d9c2b668b77555cae769ec1fa282efb689e4601d Mon Sep 17 00:00:00 2001 From: sub0br Date: Mon, 10 Aug 2026 20:35:57 -0300 Subject: [PATCH 1/3] ci: add GitHub Actions workflow to run Robot Framework suite Adds .github/workflows/robot-tests.yml to run the test suite automatically on pull requests and merges into main. - Sets up Python 3.11 and Node 22 (required by robotframework-browser) - Installs dependencies from requirements.txt - Caches Playwright browsers to speed up rfbrowser init - Runs tests/ and fails the job if any test breaks - Uploads log.html, report.html, output.xml and xunit.xml as artifacts --- .github/workflows/robot-tests.yml | 84 +++++++++++++++++++++++++++++++ README.md | 80 +++++++++++++++++++++++++++-- 2 files changed, 161 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/robot-tests.yml diff --git a/.github/workflows/robot-tests.yml b/.github/workflows/robot-tests.yml new file mode 100644 index 0000000..5409460 --- /dev/null +++ b/.github/workflows/robot-tests.yml @@ -0,0 +1,84 @@ +name: Robot Framework Tests + +on: + pull_request: + branches: [ main ] + push: + branches: [ main ] + workflow_dispatch: {} # allows manual trigger from the Actions tab + +concurrency: + group: robot-tests-${{ github.ref }} + cancel-in-progress: true + +jobs: + robot-tests: + name: Run Robot Framework Suite + runs-on: ubuntu-latest + timeout-minutes: 30 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + cache: 'pip' + + - name: Set up Node.js (required by the Browser library driver) + uses: actions/setup-node@v4 + with: + node-version: '22' + + - name: Install Python dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Cache Playwright browsers + uses: actions/cache@v4 + id: playwright-cache + with: + path: ~/.cache/ms-playwright + key: playwright-${{ runner.os }}-${{ hashFiles('requirements.txt') }} + + - name: Install browsers (rfbrowser init) + run: rfbrowser init + # Skips downloading binaries when the cache hits; rfbrowser is idempotent + # and fast once the browsers are already cached. + + - name: Run Robot Framework tests + run: | + robot \ + --outputdir results \ + --xunit xunit.xml \ + tests/ + continue-on-error: false # PR/merge must fail if any test breaks + + - name: Publish summary on GitHub Actions + if: always() + run: | + { + echo "### Robot Framework Suite Result" + if [ -f results/output.xml ]; then + echo "Full report available in the **robot-framework-results** artifact." + fi + } >> "$GITHUB_STEP_SUMMARY" + + - name: Upload artifacts (log.html, report.html, output.xml) + if: always() + uses: actions/upload-artifact@v4 + with: + name: robot-framework-results + path: results/ + retention-days: 15 + + - name: Upload JUnit/xUnit report + if: always() + uses: actions/upload-artifact@v4 + with: + name: robot-junit-report + path: xunit.xml + retention-days: 15 \ No newline at end of file diff --git a/README.md b/README.md index 19542ae..16c2684 100644 --- a/README.md +++ b/README.md @@ -28,18 +28,25 @@ them easier to read and maintain. ```text robotframework/ +├── .github/ +│ └── workflows/ +│ └── robot-tests.yml ├── requirements.txt ├── resources/ │ ├── api/ │ │ └── users_api.resource │ ├── pages/ +│ │ ├── global_page.resource │ │ ├── home_page.resource -│ │ └── login_page.resource +│ │ ├── login_page.resource +│ │ └── store_page.resource │ └── variables/ │ └── global.resource └── tests/ - └── login/ - └── login.robot + ├── login/ + │ └── login.robot + └── store/ + └── store.robot ``` ### `requirements.txt` @@ -65,6 +72,21 @@ Global variables shared across the whole project: Also loads the `Browser` and `DebugLibrary` libraries, so any resource that imports this file has access to them. +### `resources/pages/global_page.resource` + +Shared setup/teardown keywords used by more than one test suite (login and +store), gluing together the API resource and the page objects to open the +browser and prepare/clean up test data: + +- **Keywords**: + - `Open Login Page` — opens a new browser/context/page already on the + login screen. + - `Prepare Login Test` — creates a valid user via the API and opens the + login page, leaving `${EMAIL}`, `${PASSWORD}`, and `${USER_ID}` + available as test variables for the test and its teardown. + - `Cleanup Login Test` — closes the browser and removes, via the API, the + user created in the setup. + ### `resources/pages/login_page.resource` Page object for the login screen (`${BASE_URL}/login`). Contains: @@ -92,6 +114,26 @@ successful login. Contains: redirect happens client-side (SPA), asynchronously after clicking "Entrar". +### `resources/pages/store_page.resource` + +Page object for the store/home screen's shopping list feature. Contains: + +- **Locators**: `${HOME_BUTTON}`, `${ADD_TO_LIST_BUTTON}`, + `${CLEAR_LIST_BUTTON}`, `${CART_LIST_EMPTY}`. +- **Keywords**: + - `Back To Home` — clicks the "Página Inicial" button to return to the + home page. + - `Clear List` — clicks the button to clear the shopping list. + - `Add Item To List` — finds a product card by its name and clicks the + button to add it to the shopping list. + - `Item Should Be In List` — verifies that the given product is visible + in the shopping cart list. + - `Increase Quantity of Item in List` — clicks the button to increase the + quantity of an item already in the shopping list. + - `Item Should Be Increased` — verifies that the quantity of the given + product has been increased in the shopping list. + - `List Should Be Empty` — verifies that the shopping list is empty. + ### `resources/api/users_api.resource` Support keywords that call the ServeRest REST API to prepare and clean up @@ -122,6 +164,38 @@ keywords used by the test cases (e.g. `this user types the email`, `clicks on Entrar`, `the message "..." must appear`), which simply delegate to the page object keywords described above. +### `tests/store/store.robot` + +Test suite covering the shopping list on the ServeRest store/home page. It +reuses `Prepare Login Test`/`Cleanup Login Test` (via `Open Browser To Home +Page`) to log in as a fresh API-created user before each test, then drives +the store page object to run scenarios such as: + +- Adding two items to the shopping list. +- Increasing the quantity of an item already in the list. +- Clearing the shopping list. + +The `*** Keywords ***` section of this file defines the Given/When/Then +style keywords used by the test cases (e.g. `the user adds the first item to +the list`, `the user clears the list`), which simply delegate to the store +page object keywords described above. + +## Continuous Integration + +`.github/workflows/robot-tests.yml` runs the full suite on GitHub Actions: + +- **Triggers**: pull requests and pushes to `main`, plus manual runs via + `workflow_dispatch`. Runs are cancelled/deduped per branch (`concurrency`). +- Sets up Python and Node.js (the Browser library driver needs Node), + installs `requirements.txt`, and runs `rfbrowser init` (with the + downloaded Playwright browsers cached across runs). +- Executes `robot --outputdir results --xunit xunit.xml tests/`; the job + fails if any test fails. +- Uploads `log.html`, `report.html`, and `output.xml` as the + `robot-framework-results` artifact, and `xunit.xml` as the + `robot-junit-report` artifact (both kept for 15 days), and writes a short + summary to the GitHub Actions run. + ## Setup ```bash From 69779790c68a0522b8849e719f8e52f9b2d6575b Mon Sep 17 00:00:00 2001 From: sub0br Date: Mon, 10 Aug 2026 20:49:57 -0300 Subject: [PATCH 2/3] fix: force headless mode in CI via HEADLESS robot variable --- .github/workflows/robot-tests.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/robot-tests.yml b/.github/workflows/robot-tests.yml index 5409460..9b38406 100644 --- a/.github/workflows/robot-tests.yml +++ b/.github/workflows/robot-tests.yml @@ -52,10 +52,15 @@ jobs: - name: Run Robot Framework tests run: | robot \ + --variable HEADLESS:True \ --outputdir results \ --xunit xunit.xml \ tests/ continue-on-error: false # PR/merge must fail if any test breaks + # HEADLESS:True overrides the ${HEADLESS} variable used in + # global_page.resource's "New Browser" keyword (CLI --variable takes + # precedence over the *** Variables *** default), so the suite runs + # headless in CI while local runs keep the resource's own default. - name: Publish summary on GitHub Actions if: always() From 2f784a5d800218fbae0727b219a0827a7f928acd Mon Sep 17 00:00:00 2001 From: sub0br Date: Mon, 10 Aug 2026 20:52:36 -0300 Subject: [PATCH 3/3] fix: remove debugLibrary --- resources/variables/global.resource | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/variables/global.resource b/resources/variables/global.resource index 32718ec..4a6d379 100644 --- a/resources/variables/global.resource +++ b/resources/variables/global.resource @@ -1,7 +1,5 @@ *** Settings *** Library Browser -Library DebugLibrary - *** Variables *** ${BASE_URL} https://front.serverest.dev