Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
680fc44
Add Hurl smoke tests for examples
lovasoa Jun 2, 2026
8e34d00
Add gallery test and fix nginx socket
lovasoa Jun 2, 2026
8ecd301
Add todo example Hurl workflow
lovasoa Jun 2, 2026
90a0d56
Add user authentication Hurl workflow
lovasoa Jun 2, 2026
016801b
Add multi-step form Hurl workflow
lovasoa Jun 2, 2026
06ea963
Fix gallery upload Hurl workflow
lovasoa Jun 2, 2026
51929b8
Add CRUD authentication Hurl workflow
lovasoa Jun 2, 2026
48ccf25
Add variable-fields form Hurl workflow
lovasoa Jun 2, 2026
613467c
Add telemetry Hurl span workflow
lovasoa Jun 2, 2026
cff6528
Add cookie example Hurl workflow
lovasoa Jun 2, 2026
1d03aae
Add custom form Hurl workflow
lovasoa Jun 2, 2026
9d98123
Add master-detail Hurl workflow
lovasoa Jun 2, 2026
4753b36
Add multiple-choice Hurl workflow
lovasoa Jun 2, 2026
491c7bb
Add tiny Twitter Hurl workflow
lovasoa Jun 2, 2026
60b1195
Add light-dark toggle Hurl workflow
lovasoa Jun 2, 2026
7a55ebf
Add simple website Hurl workflow
lovasoa Jun 2, 2026
cd29518
Add rich text editor Hurl workflow
lovasoa Jun 2, 2026
9705d20
Add many-to-many form Hurl workflow
lovasoa Jun 2, 2026
1289727
Add corporate conundrum Hurl workflow
lovasoa Jun 2, 2026
6009dec
Add plots tables forms Hurl workflow
lovasoa Jun 2, 2026
fc4f2a6
Add splitwise Hurl workflow
lovasoa Jun 2, 2026
9125dda
Use htmlUnescape in splitwise Hurl assertions
lovasoa Jun 2, 2026
97510db
Add sending emails Hurl smoke test
lovasoa Jun 2, 2026
f2b14e7
Add charts custom components Hurl workflow
lovasoa Jun 2, 2026
ef68cba
Add React custom scripts Hurl workflow
lovasoa Jun 2, 2026
818886b
Add nginx example Hurl workflow
lovasoa Jun 2, 2026
dd5e63e
Add Apache example Hurl workflow
lovasoa Jun 2, 2026
b4cd464
Add remote content cards Hurl workflow
lovasoa Jun 2, 2026
3ccc6ff
Fix Hurl runner rebuilds and Pokemon smoke test
lovasoa Jun 2, 2026
7f086c0
Fix SSO compose and add database Hurl flows
lovasoa Jun 2, 2026
5c586ad
Fix telemetry Hurl compose startup
lovasoa Jun 2, 2026
1e45a0b
Add SSO and admin example Hurl flows
lovasoa Jun 2, 2026
9192dfd
Add PostGIS and official site Hurl flows
lovasoa Jun 2, 2026
c34d32f
Fix todo example SQLite permissions
lovasoa Jun 2, 2026
2c64310
Strengthen user auth Hurl flow
lovasoa Jun 2, 2026
f0dbc9f
Strengthen CRUD auth Hurl flow
lovasoa Jun 2, 2026
9ad42d1
Strengthen telemetry Hurl trace checks
lovasoa Jun 2, 2026
0d19624
Strengthen master-detail Hurl flow
lovasoa Jun 2, 2026
69ac003
Run example Hurl tests from CI image build
lovasoa Jun 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ jobs:
# DuckDB ODBC is not available for armv7
- platform: linux/arm/v7
variant: duckdb
# This build is shared with the Hurl example jobs.
- platform: linux/amd64
variant: minimal
steps:
- name: Checkout
uses: actions/checkout@v6
Expand Down Expand Up @@ -194,10 +197,123 @@ jobs:
if-no-files-found: error
retention-days: 1

docker_build_amd64_minimal:
name: docker_build (linux/amd64, minimal)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Docker meta
id: meta
uses: docker/metadata-action@v6
with:
images: ${{ env.REGISTRY_IMAGE }}
flavor: suffix=-linux-amd64
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Login to Docker Hub
if: github.event_name != 'pull_request'
uses: docker/login-action@v4
with:
username: ${{ env.REGISTRY_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build image for Hurl examples
uses: docker/build-push-action@v7
with:
context: .
platforms: linux/amd64
target: minimal
labels: ${{ steps.meta.outputs.labels }}
tags: |
${{ steps.meta.outputs.tags }}
${{ env.REGISTRY_IMAGE }}:main
outputs: type=docker,dest=${{ runner.temp }}/sqlpage.tar
cache-from: type=registry,ref=${{ env.REGISTRY_IMAGE }}:main-linux-amd64
- name: Upload SQLPage image
uses: actions/upload-artifact@v7
with:
name: sqlpage-linux-amd64-minimal-image
path: ${{ runner.temp }}/sqlpage.tar
if-no-files-found: error
retention-days: 1
- name: Build and push by digest
id: build
if: github.event_name != 'pull_request'
uses: docker/build-push-action@v7
with:
context: .
platforms: linux/amd64
target: minimal
labels: ${{ steps.meta.outputs.labels }}
push: true
tags: ${{ steps.meta.outputs.tags }}
cache-from: type=registry,ref=${{ env.REGISTRY_IMAGE }}:main-linux-amd64
cache-to: type=registry,ref=${{ env.REGISTRY_IMAGE }}:main-linux-amd64,compression=zstd,mode=max
- name: Export digest
if: github.event_name != 'pull_request'
run: |
mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v7
if: github.event_name != 'pull_request'
with:
name: digests-minimal-linux-amd64
path: /tmp/digests/*
if-no-files-found: error
retention-days: 1

hurl_examples:
runs-on: ubuntu-latest
outputs:
examples: ${{ steps.examples.outputs.examples }}
steps:
- uses: actions/checkout@v6
- id: examples
run: |
examples="$(find examples -mindepth 2 -maxdepth 2 -name test.hurl -print | sed 's#/test.hurl$##' | sort | jq -R -s -c 'split("\n")[:-1]')"
echo "examples=$examples" >> "$GITHUB_OUTPUT"
hurl:
name: hurl (${{ matrix.example }})
runs-on: ubuntu-latest
timeout-minutes: 15
needs:
- docker_build_amd64_minimal
- hurl_examples
strategy:
fail-fast: false
matrix:
example: ${{ fromJSON(needs.hurl_examples.outputs.examples) }}
steps:
- uses: actions/checkout@v6
- name: Install Hurl
env:
GH_TOKEN: ${{ github.token }}
run: |
version=8.0.0
archive="hurl-${version}-x86_64-unknown-linux-gnu.tar.gz"
gh release download "$version" --repo Orange-OpenSource/hurl --pattern "$archive" --dir /tmp
tar xzf "/tmp/$archive" -C /tmp
echo "/tmp/hurl-${version}-x86_64-unknown-linux-gnu/bin" >> "$GITHUB_PATH"
- name: Download SQLPage image
uses: actions/download-artifact@v8
with:
name: sqlpage-linux-amd64-minimal-image
path: ${{ runner.temp }}/sqlpage-image
- name: Load SQLPage image
run: |
docker load --input "${{ runner.temp }}/sqlpage-image/sqlpage.tar"
docker tag "${{ env.REGISTRY_IMAGE }}:main" "${{ env.REGISTRY_IMAGE }}:latest"
- name: Run example Hurl test
run: scripts/test-examples-hurl.sh "${{ matrix.example }}"

docker_push:
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
needs:
- docker_build_amd64_minimal
- docker_build
strategy:
matrix:
Expand Down
10 changes: 10 additions & 0 deletions examples/CRUD - Authentication/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
services:
web:
image: lovasoa/sqlpage:main
ports:
- "8080:8080"
volumes:
- ./www:/var/www
- ./sqlpage:/etc/sqlpage
environment:
DATABASE_URL: sqlite:///tmp/components.db?mode=rwc
2 changes: 1 addition & 1 deletion examples/CRUD - Authentication/sqlpage/sqlpage.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"listen_on": "localhost:8080",
"listen_on": "0.0.0.0:8080",
"database_url": "sqlite://./db/Components.sqlite?mode=rwc",
"allow_exec": false,
"web_root": "./www"
Expand Down
135 changes: 135 additions & 0 deletions examples/CRUD - Authentication/test.hurl
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# Public homepage is reachable without a session.
GET http://localhost:8080
HTTP 200
[Asserts]
header "Content-Type" contains "text/html"
body contains "Demo/Template CRUD with Authentication"
body not contains "An error occurred"

# The currencies CRUD page is protected.
GET http://localhost:8080/currencies_list.sql
HTTP 302
[Asserts]
header "Location" == "/login.sql?path=/currencies_list.sql"

GET http://localhost:8080/login.sql?path=/currencies_list.sql
HTTP 200
[Asserts]
body contains "Login"
body contains "Username"
body contains "Password"
body not contains "An error occurred"

POST http://localhost:8080/create_session.sql?path=/currencies_list.sql
[FormParams]
username: admin
password: wrong
HTTP 302
[Asserts]
header "Location" contains "login.sql"
header "Location" contains "error=1"

GET http://localhost:8080/currencies_list.sql
HTTP 302
[Asserts]
header "Location" == "/login.sql?path=/currencies_list.sql"

# Demo credentials from the example migration: admin/admin.
POST http://localhost:8080/create_session.sql?path=/currencies_list.sql
[FormParams]
username: admin
password: admin
HTTP 302
[Asserts]
header "Set-Cookie" contains "session_token="
header "Location" == "/currencies_list.sql"

# Hurl's cookie store reuses the session_token set above.
GET http://localhost:8080/currencies_list.sql
HTTP 200
[Asserts]
body contains "Currencies"
body contains "New Record"
body contains "RUR"
body contains "USD"
body not contains "An error occurred"

GET http://localhost:8080/currencies_item_form.sql?id=1
HTTP 200
[Asserts]
body contains "Currency"
body contains "Exchange Rate to RUR"
body contains "RUR"
body not contains "An error occurred"

GET http://localhost:8080/currencies_item_form.sql?action=INSERT
HTTP 200
[Asserts]
body contains "Currency"
body contains "Exchange Rate to RUR"
body contains "BROWSE"
body not contains "An error occurred"

POST http://localhost:8080/currencies_item_dml.sql?path=currencies_list.sql&action=UPDATE
[FormParams]
id:
name: HURLTEST
to_rub: 7.89
HTTP 302
[Captures]
currency_id: header "Location" regex "id=(\\d+)"
[Asserts]
header "Location" contains "currencies_list.sql"
header "Location" contains "info=INSERT"

GET http://localhost:8080/currencies_list.sql
HTTP 200
[Asserts]
body contains "HURLTEST"
body contains "7.89"
body htmlUnescape contains "currencies_item_form.sql?&path=/currencies_list.sql&id={{currency_id}}"
body not contains "An error occurred"

POST http://localhost:8080/currencies_item_dml.sql?path=currencies_list.sql&action=UPDATE
[FormParams]
id: {{currency_id}}
name: HURLEDITED
to_rub: 8.91
HTTP 302
[Asserts]
header "Location" contains "currencies_list.sql"
header "Location" contains "id={{currency_id}}"
header "Location" contains "info=UPDATE"

GET http://localhost:8080/currencies_item_form.sql?id={{currency_id}}
HTTP 200
[Asserts]
body contains "HURLEDITED"
body contains "8.91"
body not contains "An error occurred"

POST http://localhost:8080/currencies_item_dml.sql?path=currencies_list.sql&action=DELETE
[FormParams]
id: {{currency_id}}
name: HURLEDITED
to_rub: 8.91
HTTP 302
[Asserts]
header "Location" contains "currencies_list.sql"
header "Location" contains "info=DELETE"

GET http://localhost:8080/currencies_list.sql
HTTP 200
[Asserts]
body not contains "HURLEDITED"
body not contains "An error occurred"

GET http://localhost:8080/logout.sql?path=currencies_list.sql
HTTP 302
[Asserts]
header "Location" == "currencies_list.sql"

GET http://localhost:8080/currencies_list.sql
HTTP 302
[Asserts]
header "Location" == "/login.sql?path=/currencies_list.sql"
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
services:
web:
image: lovasoa/sqlpage:main
ports:
- "8080:8080"
volumes:
- .:/var/www
- ./sqlpage:/etc/sqlpage
depends_on:
- db
environment:
DATABASE_URL: postgres://postgres:postgres@db/postgres
db:
image: postgis/postgis:latest
platform: linux/amd64
environment:
POSTGRES_PASSWORD: postgres
53 changes: 53 additions & 0 deletions examples/PostGIS - using sqlpage with geographic data/test.hurl
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
GET http://localhost:8080/
HTTP 200
[Asserts]
body contains "Points of interest"
body contains "Add a point"
body not contains "An error occurred"

POST http://localhost:8080/add_point.sql
[FormParams]
Title: Hurl Paris
Latitude: 48.8566
Longitude: 2.3522
Text: First Hurl point
HTTP 302
[Asserts]
header "Location" == "index.sql"

POST http://localhost:8080/add_point.sql
[FormParams]
Title: Hurl Lyon
Latitude: 45.764
Longitude: 4.8357
Text: Second Hurl point
HTTP 302

GET http://localhost:8080/
HTTP 200
[Captures]
paris_id: xpath "substring-after(string(//a[normalize-space(.)='Hurl Paris']/@href), 'id=')"
[Asserts]
body contains "Hurl Paris"
body contains "Hurl Lyon"
body htmlUnescape contains "point.sql?id={{paris_id}}"
body not contains "An error occurred"

GET http://localhost:8080/point.sql?id={{paris_id}}
HTTP 200
[Asserts]
body contains "48.8566"
body contains "2.3522"
body contains "First Hurl point"
body contains "Closest points"
body contains "Hurl Lyon"
body htmlUnescape contains "edition_form.sql?id={{paris_id}}"
body not contains "An error occurred"

POST http://localhost:8080/edition_form.sql?id={{paris_id}}
[FormParams]
Text: Updated Hurl point
HTTP 200
[Asserts]
body contains "Updated Hurl point"
body not contains "An error occurred"
3 changes: 0 additions & 3 deletions examples/SQLPage developer user interface/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ services:
environment:
DATABASE_URL: postgres://root:secret@db/sqlpage
db: # The DB environment variable can be set to "mariadb" or "postgres" to test the code with different databases
ports:
- "5432:5432"
- "3306:3306"
image: postgres
environment:
POSTGRES_USER: root
Expand Down
Loading
Loading