From 0301fd2f0bc22a26ee8d71ec41dab2bce0d38dc3 Mon Sep 17 00:00:00 2001 From: Jens Tirsvad Nielsen Date: Wed, 28 Oct 2026 18:20:47 +0800 Subject: [PATCH 1/2] Add wiki in three languages, README screenshot section and wiki workflows (MIL-008) --- .gitea/workflows/publish-wiki.yml | 41 +++++++++++ .gitea/workflows/sync-milestones.yml | 73 ++++++++++++++++++++ README.md | 17 +++++ docs/artifact-registry.md | 2 +- docs/sqa/reviews/rc-022-workflows-mil-008.md | 68 ++++++++++++++++++ docs/sqa/traceability-matrix.md | 5 +- docs/wiki/Getting-Started-da.md | 65 +++++++++++++++++ docs/wiki/Getting-Started-ms.md | 65 +++++++++++++++++ docs/wiki/Getting-Started.md | 65 +++++++++++++++++ docs/wiki/Home-da.md | 25 +++++++ docs/wiki/Home-ms.md | 25 +++++++ docs/wiki/Home.md | 25 +++++++ docs/wiki/Step-1-da.md | 17 +++++ docs/wiki/Step-1-ms.md | 17 +++++ docs/wiki/Step-1.md | 17 +++++ docs/wiki/Step-2-da.md | 19 +++++ docs/wiki/Step-2-ms.md | 19 +++++ docs/wiki/Step-2.md | 19 +++++ docs/wiki/Step-3-da.md | 19 +++++ docs/wiki/Step-3-ms.md | 19 +++++ docs/wiki/Step-3.md | 19 +++++ docs/wiki/Step-4-da.md | 19 +++++ docs/wiki/Step-4-ms.md | 19 +++++ docs/wiki/Step-4.md | 19 +++++ docs/wiki/Step-5-da.md | 19 +++++ docs/wiki/Step-5-ms.md | 19 +++++ docs/wiki/Step-5.md | 19 +++++ docs/wiki/Step-6-da.md | 19 +++++ docs/wiki/Step-6-ms.md | 19 +++++ docs/wiki/Step-6.md | 19 +++++ docs/wiki/Step-7-da.md | 19 +++++ docs/wiki/Step-7-ms.md | 19 +++++ docs/wiki/Step-7.md | 19 +++++ docs/wiki/Step-8-da.md | 19 +++++ docs/wiki/Step-8-ms.md | 19 +++++ docs/wiki/Step-8.md | 19 +++++ docs/wiki/Step-9-da.md | 19 +++++ docs/wiki/Step-9-ms.md | 19 +++++ docs/wiki/Step-9.md | 19 +++++ docs/wiki/Troubleshooting-da.md | 12 ++++ docs/wiki/Troubleshooting-ms.md | 12 ++++ docs/wiki/Troubleshooting.md | 12 ++++ docs/wiki/_Footer.md | 1 + docs/wiki/_Sidebar.md | 11 +++ 44 files changed, 1028 insertions(+), 3 deletions(-) create mode 100644 .gitea/workflows/publish-wiki.yml create mode 100644 .gitea/workflows/sync-milestones.yml create mode 100644 docs/sqa/reviews/rc-022-workflows-mil-008.md create mode 100644 docs/wiki/Getting-Started-da.md create mode 100644 docs/wiki/Getting-Started-ms.md create mode 100644 docs/wiki/Getting-Started.md create mode 100644 docs/wiki/Home-da.md create mode 100644 docs/wiki/Home-ms.md create mode 100644 docs/wiki/Home.md create mode 100644 docs/wiki/Step-1-da.md create mode 100644 docs/wiki/Step-1-ms.md create mode 100644 docs/wiki/Step-1.md create mode 100644 docs/wiki/Step-2-da.md create mode 100644 docs/wiki/Step-2-ms.md create mode 100644 docs/wiki/Step-2.md create mode 100644 docs/wiki/Step-3-da.md create mode 100644 docs/wiki/Step-3-ms.md create mode 100644 docs/wiki/Step-3.md create mode 100644 docs/wiki/Step-4-da.md create mode 100644 docs/wiki/Step-4-ms.md create mode 100644 docs/wiki/Step-4.md create mode 100644 docs/wiki/Step-5-da.md create mode 100644 docs/wiki/Step-5-ms.md create mode 100644 docs/wiki/Step-5.md create mode 100644 docs/wiki/Step-6-da.md create mode 100644 docs/wiki/Step-6-ms.md create mode 100644 docs/wiki/Step-6.md create mode 100644 docs/wiki/Step-7-da.md create mode 100644 docs/wiki/Step-7-ms.md create mode 100644 docs/wiki/Step-7.md create mode 100644 docs/wiki/Step-8-da.md create mode 100644 docs/wiki/Step-8-ms.md create mode 100644 docs/wiki/Step-8.md create mode 100644 docs/wiki/Step-9-da.md create mode 100644 docs/wiki/Step-9-ms.md create mode 100644 docs/wiki/Step-9.md create mode 100644 docs/wiki/Troubleshooting-da.md create mode 100644 docs/wiki/Troubleshooting-ms.md create mode 100644 docs/wiki/Troubleshooting.md create mode 100644 docs/wiki/_Footer.md create mode 100644 docs/wiki/_Sidebar.md diff --git a/.gitea/workflows/publish-wiki.yml b/.gitea/workflows/publish-wiki.yml new file mode 100644 index 0000000..bf8a707 --- /dev/null +++ b/.gitea/workflows/publish-wiki.yml @@ -0,0 +1,41 @@ +# Publish the project's wiki pages to the git host's wiki. +# +# On a push to main that changes docs/wiki/, this workflow calls the reusable +# workflow of TirSystem/github-action, which copies the Markdown pages of +# docs/wiki/ to the wiki of this repository (framework/process/wiki.md says +# what the folder holds: English and the PO language as a minimum). +# +# INSTALLING THIS FILE IS THE OPT-IN. There is no marker file. A project that +# does not copy it publishes nothing. +# +# Copy it to .gitea/workflows/publish-wiki.yml. Then: +# 1. Create the secret TOKEN_FOR_GITEA_WIKI in the organization of the +# repository: a Gitea token with scope write:repository for a user that +# can write this repository (see guides/credentials.md of github-action). +# 2. Enable the wiki in the repository settings. +# 3. Keep @v1, or pin the exact release tag together with tools-ref. +# A runner must be registered for the repository (or its organization). +# +# prune: "true" deletes wiki pages that are not in docs/wiki/, so the wiki +# always equals the folder. Leave it "false" to keep hand-written pages. + +name: Publish wiki + +on: + push: + branches: [ main ] + paths: + - "docs/wiki/**" + workflow_dispatch: + +permissions: + contents: read + +jobs: + wiki: + uses: TirSystem/git-workflows/.gitea/workflows/publish-wiki-pages.yml@v1 + with: + wiki_dir: docs/wiki + prune: "true" + secrets: + TOKEN_FOR_GITEA_WIKI: ${{ secrets.TOKEN_FOR_GITEA_WIKI }} diff --git a/.gitea/workflows/sync-milestones.yml b/.gitea/workflows/sync-milestones.yml new file mode 100644 index 0000000..a865091 --- /dev/null +++ b/.gitea/workflows/sync-milestones.yml @@ -0,0 +1,73 @@ +# Publish accepted milestones to the git host. +# +# On a push to main that changes docs/milestones/ or docs/sqa/reviews/, this +# workflow runs `sync-project.sh --accepted-only --apply`: every milestone whose +# latest Version History row is Accepted and whose latest review record is a Go +# is created or updated as a Milestone with its tasks as Issues. A Proposed +# milestone, or one without a Go review, is skipped. Nothing is closed or +# deleted. Each run updates the issues of every accepted milestone (the sync is +# idempotent, but the host records the edit). +# +# INSTALLING THIS FILE IS THE STANDING AUTHORIZATION TO PUBLISH. A project opts +# in by copying it; an agent does not install it on its own. +# +# Copy it to .gitea/workflows/sync-milestones.yml (Gitea Actions) or +# .github/workflows/sync-milestones.yml (GitHub Actions). Then: +# 1. Create a CI secret and put its name in the two `secrets.` lines below +# (SYNC_TOKEN is a placeholder). Gitea does not accept secret names that +# start with GITEA_ or GITHUB_. +# 2. Give the token the smallest scope that works: read and write on issues +# and milestones. If the framework submodule is a private repository, the +# token must also be able to read it (it is used to check it out). +# 3. Run it once by hand from the Actions page with dry_run left on: it prints +# the plan and creates nothing. Turn dry_run off only for a real run. +# A runner must be registered for the repository (or its organisation). +# +# The steps are one command each: the logic is framework/scripts/ci-publish-milestones.sh, +# a file that is linted and tested (QC-WF-001 criterion 20). + +name: Publish accepted milestones + +on: + push: + branches: [main] + paths: + - "docs/milestones/**" + - "docs/sqa/reviews/**" + workflow_dispatch: + inputs: + dry_run: + description: "Preview only: print the plan and create nothing" + type: boolean + default: true + +# Two merges in a row queue instead of racing. +concurrency: + group: publish-accepted-milestones + cancel-in-progress: false + +jobs: + publish: + permissions: + contents: read + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - name: Check out the project and its framework submodule + uses: actions/checkout@v4.2.2 + with: + submodules: recursive + token: ${{ secrets.SYNC_TOKEN }} + + - name: Make sure curl and jq are available + run: bash framework/scripts/ci-publish-milestones.sh ensure-tools + + - name: Publish accepted milestones + env: + # Gitea reads GITEA_TOKEN, GitHub's gh reads GH_TOKEN; both come from + # the one secret named above. + GITEA_TOKEN: ${{ secrets.SYNC_TOKEN }} + GH_TOKEN: ${{ secrets.SYNC_TOKEN }} + # Empty on a push (a real run); "true" or "false" on a manual run. + DRY_RUN: ${{ inputs.dry_run }} + run: bash framework/scripts/ci-publish-milestones.sh publish diff --git a/README.md b/README.md index d24acfe..3ad11ec 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ A Selenium bot that books classes at the fictional gym "Snack and Lift" for you: - [Requirements](#-requirements) - [Setup](#-setup) - [Run](#-run) +- [Lecture steps and screenshots](#-lecture-steps-and-screenshots) - [Tests](#-tests) - [License](#-license) - [Links](#-links) @@ -112,6 +113,22 @@ docker build -t snack-and-lift . docker run --rm snack-and-lift ``` +## 📸 Lecture steps and screenshots + +Each step has a wiki page that explains what it teaches, in [English](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/wiki/Home), [Dansk](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/wiki/Home-da) and [Bahasa Melayu](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/wiki/Home-ms). Only the screenshot of step 1 is in the repository yet: the others need a run with a real gym account, which the maintainer makes with `--screenshot-dir` (see [Getting started](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/wiki/Getting-Started)). Until then their images do not show. + +| Step | Wiki page | Screenshot | +| --- | --- | --- | +| 1 | [Setup and navigation](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/wiki/Step-1) | ![Step 1](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-1.png) | +| 2 | [Automated login](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/wiki/Step-2) | ![Step 2](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-2.png) | +| 3 | [Book the next Tuesday class](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/wiki/Step-3) | ![Step 3](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-3.png) | +| 4 | [Check if a class is booked](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/wiki/Step-4) | ![Step 4](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-4.png) | +| 5 | [Counters and summary](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/wiki/Step-5) | ![Step 5](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-5.png) | +| 6 | [Every Tuesday and Thursday class](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/wiki/Step-6) | ![Step 6](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-6.png) | +| 7 | [Verify on My Bookings](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/wiki/Step-7) | ![Step 7](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-7.png) | +| 8 | [Time travel QA](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/wiki/Step-8) | ![Step 8](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-8.png) | +| 9 | [Resilience (retry)](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/wiki/Step-9) | ![Step 9](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-9.png) | + ## 🧪 Tests ```bash diff --git a/docs/artifact-registry.md b/docs/artifact-registry.md index 358447e..61617f8 100644 --- a/docs/artifact-registry.md +++ b/docs/artifact-registry.md @@ -16,7 +16,7 @@ document of a type. `Primary File` may contain a glob (e.g. | PP | Project Plan | docs/project-plan.md | 002 | | MIL | Milestone / Gateway | docs/milestones/*.md | 009 | | ADR | Architecture Decision Record | docs/adr/adr-NNNN-*.md | 0004 | -| RC | SQA Review Record | docs/sqa/reviews/rc-*.md | 022 | +| RC | SQA Review Record | docs/sqa/reviews/rc-*.md | 023 | | TM | Traceability Matrix | docs/sqa/traceability-matrix.md | 002 | | DICT | Domain Dictionary | docs/dictionary.md | 002 | diff --git a/docs/sqa/reviews/rc-022-workflows-mil-008.md b/docs/sqa/reviews/rc-022-workflows-mil-008.md new file mode 100644 index 0000000..779ab99 --- /dev/null +++ b/docs/sqa/reviews/rc-022-workflows-mil-008.md @@ -0,0 +1,68 @@ +# SQA Review Record + +## Metadata +| Key | Value | +| --- | --- | +| ID | RC-022 | +| CrossReference | [MIL-008], [QC-WF-001] | + +## Version History +| Date | Status | Author | Reviewer | Change | Commit | +| --- | --- | --- | --- | --- | --- | +| 2026-10-28 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S02 | Review record, the workflows publish-wiki.yml and sync-milestones.yml of MIL-008 task 5 | pending | + +--- + +## Artifact Under Review + +- Instance reviewed: [MIL-008] +- Checklist used: [QC-WF-001] (`QC-WF-001`) +- Scope: the workflows publish-wiki.yml and sync-milestones.yml of MIL-008 task 5 +- Language and domain: n/a +- Language reviewer: none +- Mode: autonomous, not independent (the reviewer is `AI as stand-in for S02`) + +## Checklist Results + +| # | Criterion | Status | Evidence/Notes | +| --- | --- | --- | --- | +| 1 | The file meets the YAML checklist ([QC-YML-001]) | Pending | `yamllint` is not installed on the stand-in's machine, so the YAML checklist QC-YML-001 was not run; the files parse (actionlint reads them) and use 2-space indentation. | +| 2 | The file is in `.gitea/workflows/` or `.github/workflows/` with the extension `.yml` or `.yaml`, and the same workflow does not exist in both directories | Pass | Both files are in `.gitea/workflows/` with the extension `.yml`; neither exists in `.github/workflows/`. | +| 3 | The file declares `name`, `on` and `jobs`; `on` lists explicit events and, where it matters, `branches` or `paths` | Pass | Both files declare `name`, `on` and `jobs`; `on` lists `push` on `main` with `paths`, and `workflow_dispatch`. | +| 4 | A header comment states the purpose, the triggers, the inputs, the secrets it needs, what it changes outside the repository, and the decision or milestone it implements | Pass | Both headers state the purpose, triggers, secrets, what changes outside the repository and the installation steps (copied from the framework template); the decision is MIL-008 task 5. | +| 5 | Every job and step has a descriptive `name`, unique within its job | Pass | `sync-milestones.yml` names every step. `publish-wiki.yml` has one job that calls a reusable workflow and has no steps of its own. | +| 6 | The file passes `actionlint` (or the project's workflow validation test) and the tool version is stated | Pass | `actionlint` 1.7.12 reports no finding for both files (exit code 0). | +| 7 | Every job declares `permissions` explicitly with the least access that works (`contents: read` or none by default); write access only on the job that needs it | Pass | `sync-milestones.yml` sets `contents: read` on its job; `publish-wiki.yml` sets `contents: read` for the whole workflow (added to the framework template). The wiki write uses the token secret. | +| 8 | Every action used is pinned to a full commit SHA or an exact release tag, never to a branch; a moving major tag (`@v1`) is accepted only for an action published by the same organisation under a stated release policy | Pass | `actions/checkout@v4.2.2` is an exact release tag. `publish-wiki.yml` uses `TirSystem/git-workflows/.gitea/workflows/publish-wiki-pages.yml@v1`, a moving major tag of a reusable workflow of the same organisation, which the framework template accepts. | +| 9 | No secret is written in the file; a secret is read as `secrets.NAME`, passed to a step through `env:`, never placed on a command line or echoed | Pass | Both files read `secrets.SYNC_TOKEN` and `secrets.TOKEN_FOR_GITEA_WIKI` only; no secret value is in the repository. | +| 10 | Untrusted text (`inputs.*`, event fields such as a title, branch name or label, step outputs derived from them) is never interpolated into a `run:` script; it is passed through `env:` and used as a quoted variable | Pass | No `run:` block interpolates `inputs.*` or event text; `DRY_RUN` is passed through `env:`. | +| 11 | A trigger that gives a run secrets or a write token on code from a fork or an untrusted branch (`pull_request_target`, `workflow_run`) does not check out or execute that code | Pass | Neither workflow uses `pull_request_target` or `workflow_run`. | +| 12 | A workflow that changes state outside the repository (release, tag, publish, sync, deploy) is started by hand or by a protected branch, and a manual run defaults to a dry run with an explicit input to apply | Pass | Both run on a push to `main` or by hand; the manual run of `sync-milestones.yml` defaults to a dry run. `publish-wiki.yml` has no dry run (it is a call of the reusable workflow). | +| 13 | The token the workflow uses has only the scope the job needs, and where the host's built-in token is enough it is used instead of a personal token | Pending | The scope of both tokens is set by S01 when the secrets are created. | +| 14 | Every job sets `runs-on` to an explicit label and `timeout-minutes` | Pass | `sync-milestones.yml` sets `runs-on: ubuntu-latest` and `timeout-minutes: 15`. `publish-wiki.yml` calls a reusable workflow, where the called workflow sets them (a calling job cannot). | +| 15 | `concurrency` is set where two runs would conflict: a check cancels the older run (`cancel-in-progress: true`); a publishing job queues (`cancel-in-progress: false`) | Pass | `sync-milestones.yml` sets `concurrency` with `cancel-in-progress: false`; `publish-wiki.yml` leaves it to the reusable workflow. | +| 16 | Triggers are filtered (`branches`, `paths`, `types`) so the workflow runs only for the changes it concerns | Pass | Both are filtered by `branches: [main]` and `paths`. | +| 17 | Tools and dependencies are installed at pinned versions; a version is a workflow input with a default or a value in one place | Pass | `sync-milestones.yml` installs nothing itself; `curl` and `jq` are checked by the framework script. The wiki workflow installs nothing. | +| 18 | A dependency cache is used where the install is slow enough to matter | N-A | No dependency is installed that a cache would speed up. | +| 19 | A failing step names the tool, the file and the reason in its log (annotation or `::error::` line) | Pending | Not verified: the log messages come from the framework script and the reusable workflow, which the stand-in did not run. | +| 20 | A `run:` block is within the limit on embedded program text of criterion 7 of [QC-YML-001]; a longer script is a file (`tools/`, or a shared repository fetched at a pinned ref) that the step calls with one command, and the workflow passes its settings through `env:` | Pass | Each `run:` block is one command; the logic is in `framework/scripts/ci-publish-milestones.sh`. | +| 21 | Logic used by more than one workflow or repository is a reusable workflow (`workflow_call`) or a composite action; each input has a `description`, a `type` and a `default` where one is sensible | Pass | `publish-wiki.yml` calls the reusable workflow; `sync-milestones.yml` calls one framework script. The inputs of `workflow_dispatch` have a description, type and default. | +| 22 | Every workflow feature used is verified on the instance that runs it, and the host and version are recorded; a feature the target hosts differ on is noted in the header | Pending | Neither workflow has run on the Gitea instance yet: the secrets do not exist and a merge to `main` is what triggers the first run. | +| 23 | A reusable workflow states, in its header, how a caller pins it and the script it fetches, so the workflow and its script are the same release | N-A | Neither file is a reusable workflow; both are callers. | +| 24 | A static test of the repository's workflows exists and runs on every pull request: valid YAML, required keys, explicit permissions and runner, no inline script above the limit | N-A | No static test of the workflows exists in this project; the checks are `actionlint` on request. | + +## Overall Verdict + +Go-with-conditions - the two workflows are the framework's templates, copied into `.gitea/workflows/`, and pass `actionlint`. Mandatory criteria 1 (the YAML checklist: `yamllint` was not run) and 22 (feature checked on the instance) are Pending, because the stand-in cannot create the secrets `TOKEN_FOR_GITEA_WIKI` and `SYNC_TOKEN` or watch a run on the host. The workflows will fail or skip until S01 creates them. The review is not independent: the AI wrote and reviewed it as stand-in for S02, and S01 can challenge it in the end-of-run summary. + +## Action Items + +| Action | Owner | Due | +| --- | --- | --- | +| Create the secrets `TOKEN_FOR_GITEA_WIKI` (wiki write) and `SYNC_TOKEN` (issues and milestones) in the organisation, enable the wiki, then run both workflows once by hand | S01 | before the next merge to main | +| Run `yamllint` on `.gitea/workflows/` | S01 | when convenient | + +--- + +[MIL-008]: ../../milestones/mil-008-documentation.md +[QC-WF-001]: ../../../framework/qc/code/qc-workflow.md diff --git a/docs/sqa/traceability-matrix.md b/docs/sqa/traceability-matrix.md index f6ea5b6..4694ea3 100644 --- a/docs/sqa/traceability-matrix.md +++ b/docs/sqa/traceability-matrix.md @@ -42,6 +42,7 @@ Tracks backward and forward links between artifact instances so that the Busines | Source and tests of [MIL-005] | Python source code | - | - | [MIL-005], [ADR-0002] | - | RC-019 (Go-with-conditions) | | Source and tests of [MIL-006] | Python source code | - | - | [MIL-006], [ADR-0002] | - | RC-020 (Go-with-conditions) | | Source and tests of [MIL-007] | Python source code | - | - | [MIL-007], [ADR-0002] | - | RC-021 (Go-with-conditions) | +| Workflows and wiki of [MIL-008] | Workflow files, wiki pages | - | - | [MIL-008] | - | RC-022 (Go-with-conditions) | ## Concern Coverage @@ -51,8 +52,8 @@ Tracks backward and forward links between artifact instances so that the Busines | CN-002 | [PP-001], [MIL-001] | [ADR-0001] | Review records RC-001 onward | Covered | | CN-003 | [MIL-006], [MIL-007] | [ADR-0002] | Unit tests of `retry`; container chaos run | Planned | | CN-004 | [MIL-003] to [MIL-007] | [ADR-0002] | Code review against QC-PY-001 | Planned | -| CN-005 | [MIL-002], [MIL-008] | - | `check-readme.sh` | Planned | -| CN-006 | [MIL-008] | - | Page count per language | Planned | +| CN-005 | [MIL-002], [MIL-008] | - | `check-readme.sh` | Covered | +| CN-006 | [MIL-008] | - | Page count per language (12 pages in each of en, da, ms) | Covered | | CN-007 | [MIL-001] | - | Repository API response | Covered | | CN-008 | [MIL-002] | [ADR-0002] | `pyproject.toml` | Planned | | CN-009 | [MIL-001] | - | `.gitignore` lists `.env` | Covered | diff --git a/docs/wiki/Getting-Started-da.md b/docs/wiki/Getting-Started-da.md new file mode 100644 index 0000000..c9c1cf5 --- /dev/null +++ b/docs/wiki/Getting-Started-da.md @@ -0,0 +1,65 @@ +[English](Getting-Started) · **Dansk** · [Bahasa Melayu](Getting-Started-ms) + +# Kom i gang + +## Krav + +Python 3.13 eller nyere, Chrome eller Chromium og (valgfrit) Docker. + +## Installation + +```bash +python -m venv .venv +``` + +```bash +source .venv/bin/activate +``` + +```powershell +.venv\Scripts\Activate.ps1 +``` + +```bash +python -m pip install --upgrade pip +python -m pip install -e ".[dev]" +``` + +## Din konto + +Botten indeholder ingen adgangskode. Opret en konto én gang i hånden på siden (kør med `--keep-open`, så mappen `chrome_profile` gemmer sidens data), og giv derefter botten kontoen: + +```bash +export SNACK_AND_LIFT_EMAIL="yourname@test.com" +export SNACK_AND_LIFT_PASSWORD="your password" +``` + +```powershell +$env:SNACK_AND_LIFT_EMAIL = "yourname@test.com" +$env:SNACK_AND_LIFT_PASSWORD = "your password" +``` + +## Kør og test + +```bash +snack-and-lift +``` + +```bash +python -m pytest +``` + +Nyttige indstillinger: `--headless`, `--keep-open`, `--first-tuesday-only` (trin 3 og 4), `--retries N`, `--profile-dir DIR`, `--screenshot-dir DIR`. + +## Exitkoder + +0 færdig, 1 et trin fejlede (også når alle forsøg fejlede), 2 loginoplysninger mangler, 3 siden My Bookings passer ikke med de bookinger der blev lavet. + +## Skærmbilleder (vedligeholder) + +Siden gemmer sine data i browserens profil, så en kørsel i en container kræver en konto der findes i den profil. Brug `--env-file` til loginoplysningerne (aldrig på kommandolinjen eller i repositoriet) og et volume til profilen og skærmbillederne: + +```bash +docker build -t snack-and-lift . +docker run --rm --env-file my.env -v snack-profile:/app/chrome_profile -v "$PWD/docs/images:/app/screenshots" snack-and-lift --headless --screenshot-dir /app/screenshots +``` diff --git a/docs/wiki/Getting-Started-ms.md b/docs/wiki/Getting-Started-ms.md new file mode 100644 index 0000000..e52e67e --- /dev/null +++ b/docs/wiki/Getting-Started-ms.md @@ -0,0 +1,65 @@ +[English](Getting-Started) · [Dansk](Getting-Started-da) · **Bahasa Melayu** + +# Mula menggunakan + +## Keperluan + +Python 3.13 atau lebih baharu, Chrome atau Chromium, dan (pilihan) Docker. + +## Pemasangan + +```bash +python -m venv .venv +``` + +```bash +source .venv/bin/activate +``` + +```powershell +.venv\Scripts\Activate.ps1 +``` + +```bash +python -m pip install --upgrade pip +python -m pip install -e ".[dev]" +``` + +## Akaun anda + +Bot tidak mengandungi kata laluan. Daftar sekali secara manual di laman (jalankan dengan `--keep-open` supaya folder `chrome_profile` menyimpan data laman), kemudian beri bot akaun itu: + +```bash +export SNACK_AND_LIFT_EMAIL="yourname@test.com" +export SNACK_AND_LIFT_PASSWORD="your password" +``` + +```powershell +$env:SNACK_AND_LIFT_EMAIL = "yourname@test.com" +$env:SNACK_AND_LIFT_PASSWORD = "your password" +``` + +## Jalankan dan uji + +```bash +snack-and-lift +``` + +```bash +python -m pytest +``` + +Pilihan berguna: `--headless`, `--keep-open`, `--first-tuesday-only` (langkah 3 dan 4), `--retries N`, `--profile-dir DIR`, `--screenshot-dir DIR`. + +## Kod keluar + +0 selesai, 1 satu langkah gagal (juga apabila semua percubaan gagal), 2 kelayakan tiada, 3 halaman My Bookings tidak sepadan dengan tempahan yang dibuat. + +## Mengambil tangkapan skrin (penyelenggara) + +Laman menyimpan datanya dalam profil pelayar, jadi larian dalam bekas memerlukan akaun yang wujud dalam profil itu. Gunakan `--env-file` untuk kelayakan (jangan pada baris arahan atau dalam repositori) dan volume untuk profil serta tangkapan skrin: + +```bash +docker build -t snack-and-lift . +docker run --rm --env-file my.env -v snack-profile:/app/chrome_profile -v "$PWD/docs/images:/app/screenshots" snack-and-lift --headless --screenshot-dir /app/screenshots +``` diff --git a/docs/wiki/Getting-Started.md b/docs/wiki/Getting-Started.md new file mode 100644 index 0000000..797291a --- /dev/null +++ b/docs/wiki/Getting-Started.md @@ -0,0 +1,65 @@ +**English** · [Dansk](Getting-Started-da) · [Bahasa Melayu](Getting-Started-ms) + +# Getting started + +## Requirements + +Python 3.13 or newer, Chrome or Chromium, and (optional) Docker. + +## Install + +```bash +python -m venv .venv +``` + +```bash +source .venv/bin/activate +``` + +```powershell +.venv\Scripts\Activate.ps1 +``` + +```bash +python -m pip install --upgrade pip +python -m pip install -e ".[dev]" +``` + +## Your account + +The bot contains no password. Register once by hand on the site (run with `--keep-open`, so the `chrome_profile` folder keeps the site's data), then give the bot the account: + +```bash +export SNACK_AND_LIFT_EMAIL="yourname@test.com" +export SNACK_AND_LIFT_PASSWORD="your password" +``` + +```powershell +$env:SNACK_AND_LIFT_EMAIL = "yourname@test.com" +$env:SNACK_AND_LIFT_PASSWORD = "your password" +``` + +## Run and test + +```bash +snack-and-lift +``` + +```bash +python -m pytest +``` + +Useful options: `--headless`, `--keep-open`, `--first-tuesday-only` (steps 3 and 4), `--retries N`, `--profile-dir DIR`, `--screenshot-dir DIR`. + +## Exit codes + +0 done, 1 a step failed (also when every retry failed), 2 credentials missing, 3 the My Bookings page does not match the bookings made. + +## Taking the screenshots (maintainer) + +The site keeps its data in the browser profile, so a container run needs an account that exists in that profile. Use `--env-file` for the credentials (never write them on the command line or into the repository) and a volume for the profile and the screenshots: + +```bash +docker build -t snack-and-lift . +docker run --rm --env-file my.env -v snack-profile:/app/chrome_profile -v "$PWD/docs/images:/app/screenshots" snack-and-lift --headless --screenshot-dir /app/screenshots +``` diff --git a/docs/wiki/Home-da.md b/docs/wiki/Home-da.md new file mode 100644 index 0000000..ea72de8 --- /dev/null +++ b/docs/wiki/Home-da.md @@ -0,0 +1,25 @@ +[English](Home) · **Dansk** · [Bahasa Melayu](Home-ms) + +# Snack and Lift-bot + +En Selenium-bot der booker hold på øvelsesgymmet [Snack and Lift](https://appbrewery.github.io/gym/). Den er løsningen på dag 49 i Udemys *100 Days of Code*. Hver side nedenfor forklarer hvad ét trin i lektionen lærer. + +Botten logger ind, booker hvert tirsdags- og torsdagshold kl. 18 (eller kommer på ventelisten), bekræfter resultatet på siden My Bookings og prøver igen når siden fejler en forespørgsel. + +- [Kom i gang](Getting-Started-da): `.venv`, din konto, kørsel og test. +- De ni trin, nedenfor. +- [Fejlfinding](Troubleshooting-da). + +Kildekode og sager: [repository](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift). + +## De ni trin + +1. [Trin 1: Opsætning, Chrome-profil og navigation](Step-1-da) +2. [Trin 2: Automatisk login](Step-2-da) +3. [Trin 3: Book næste tirsdagshold](Step-3-da) +4. [Trin 4: Tjek om et hold allerede er booket](Step-4-da) +5. [Trin 5: Tællere og et resumé](Step-5-da) +6. [Trin 6: Alle tirsdags- og torsdagshold](Step-6-da) +7. [Trin 7: Bekræft på siden My Bookings](Step-7-da) +8. [Trin 8: Kvalitetssikring med tidsrejse](Step-8-da) +9. [Trin 9: Robusthed mod netværksfejl](Step-9-da) diff --git a/docs/wiki/Home-ms.md b/docs/wiki/Home-ms.md new file mode 100644 index 0000000..b794501 --- /dev/null +++ b/docs/wiki/Home-ms.md @@ -0,0 +1,25 @@ +[English](Home) · [Dansk](Home-da) · **Bahasa Melayu** + +# Bot Snack and Lift + +Bot Selenium yang menempah kelas di gim latihan [Snack and Lift](https://appbrewery.github.io/gym/). Ia penyelesaian untuk hari 49 *100 Days of Code* Udemy. Setiap halaman di bawah menerangkan apa yang diajar oleh satu langkah kuliah. + +Bot log masuk, menempah setiap kelas Selasa dan Khamis pukul 6 petang (atau menyertai senarai menunggu), mengesahkan hasilnya di halaman My Bookings dan mencuba semula apabila laman gagal memproses permintaan. + +- [Mula menggunakan](Getting-Started-ms): `.venv`, akaun anda, menjalankan dan menguji. +- Sembilan langkah, di bawah. +- [Menyelesaikan masalah](Troubleshooting-ms). + +Kod sumber dan isu: [repository](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift). + +## Sembilan langkah + +1. [Langkah 1: Persediaan, profil Chrome dan navigasi](Step-1-ms) +2. [Langkah 2: Log masuk automatik](Step-2-ms) +3. [Langkah 3: Tempah kelas Selasa seterusnya](Step-3-ms) +4. [Langkah 4: Semak sama ada kelas sudah ditempah](Step-4-ms) +5. [Langkah 5: Pembilang dan ringkasan](Step-5-ms) +6. [Langkah 6: Semua kelas Selasa dan Khamis](Step-6-ms) +7. [Langkah 7: Sahkan di halaman My Bookings](Step-7-ms) +8. [Langkah 8: Jaminan kualiti dengan perjalanan masa](Step-8-ms) +9. [Langkah 9: Ketahanan terhadap kegagalan rangkaian](Step-9-ms) diff --git a/docs/wiki/Home.md b/docs/wiki/Home.md new file mode 100644 index 0000000..6b1c605 --- /dev/null +++ b/docs/wiki/Home.md @@ -0,0 +1,25 @@ +**English** · [Dansk](Home-da) · [Bahasa Melayu](Home-ms) + +# Snack and Lift bot + +A Selenium bot that books classes at the practice gym [Snack and Lift](https://appbrewery.github.io/gym/). It is the solution to day 49 of Udemy's *100 Days of Code*. Each page below explains what one lecture step teaches. + +The bot logs in, books every Tuesday and Thursday 6pm class (or joins the waitlist), verifies the result on the My Bookings page and retries when the site fails a request. + +- [Getting started](Getting-Started): the `.venv`, your account, running and testing. +- The nine steps, below. +- [Troubleshooting](Troubleshooting). + +Source and issues: [repository](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift). + +## The nine steps + +1. [Step 1: Setup, Chrome profile and navigation](Step-1) +2. [Step 2: Automated login](Step-2) +3. [Step 3: Book the next Tuesday class](Step-3) +4. [Step 4: Check if a class is already booked](Step-4) +5. [Step 5: Counters and a summary](Step-5) +6. [Step 6: Every Tuesday and Thursday class](Step-6) +7. [Step 7: Verify on the My Bookings page](Step-7) +8. [Step 8: Time travel quality assurance](Step-8) +9. [Step 9: Resilience against network failures](Step-9) diff --git a/docs/wiki/Step-1-da.md b/docs/wiki/Step-1-da.md new file mode 100644 index 0000000..7b10c28 --- /dev/null +++ b/docs/wiki/Step-1-da.md @@ -0,0 +1,17 @@ +[English](Step-1) · **Dansk** · [Bahasa Melayu](Step-1-ms) + +# Trin 1: Opsætning, Chrome-profil og navigation + +## Hvad du får ud af det + +Du lærer at starte Chrome fra Selenium med en egen profilmappe (`chrome_profile`), så sidens data overlever mellem kørsler, og med indstillingen `detach`, så vinduet bliver åbent når scriptet slutter. Botten åbner forsiden og venter på login-knappen i stedet for at sove. + +## Hvor det er i koden + +`src/snack_and_lift/infrastructure/browser.py` + +## Skærmbillede + +![Trin 1: Opsætning, Chrome-profil og navigation](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-1.png) + +[Forside](Home-da) · [Næste: 2](Step-2-da) diff --git a/docs/wiki/Step-1-ms.md b/docs/wiki/Step-1-ms.md new file mode 100644 index 0000000..81dd185 --- /dev/null +++ b/docs/wiki/Step-1-ms.md @@ -0,0 +1,17 @@ +[English](Step-1) · [Dansk](Step-1-da) · **Bahasa Melayu** + +# Langkah 1: Persediaan, profil Chrome dan navigasi + +## Apa yang anda peroleh + +Anda belajar memulakan Chrome daripada Selenium dengan folder profil sendiri (`chrome_profile`) supaya data laman kekal antara larian, dan dengan pilihan `detach` supaya tetingkap kekal terbuka apabila skrip tamat. Bot membuka halaman utama dan menunggu butang log masuk, bukannya tidur. + +## Di mana dalam kod + +`src/snack_and_lift/infrastructure/browser.py` + +## Tangkapan skrin + +![Langkah 1: Persediaan, profil Chrome dan navigasi](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-1.png) + +[Utama](Home-ms) · [Seterusnya: 2](Step-2-ms) diff --git a/docs/wiki/Step-1.md b/docs/wiki/Step-1.md new file mode 100644 index 0000000..080d7c3 --- /dev/null +++ b/docs/wiki/Step-1.md @@ -0,0 +1,17 @@ +**English** · [Dansk](Step-1-da) · [Bahasa Melayu](Step-1-ms) + +# Step 1: Setup, Chrome profile and navigation + +## What you gain + +You learn to start Chrome from Selenium with its own profile folder (`chrome_profile`), so the site's data survives between runs, and with the `detach` option, so the window stays open when the script ends. The bot opens the home page and waits for the login button instead of sleeping. + +## Where it is in the code + +`src/snack_and_lift/infrastructure/browser.py` + +## Screenshot + +![Step 1: Setup, Chrome profile and navigation](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-1.png) + +[Home](Home) · [Next: 2](Step-2) diff --git a/docs/wiki/Step-2-da.md b/docs/wiki/Step-2-da.md new file mode 100644 index 0000000..ef2b038 --- /dev/null +++ b/docs/wiki/Step-2-da.md @@ -0,0 +1,19 @@ +[English](Step-2) · **Dansk** · [Bahasa Melayu](Step-2-ms) + +# Trin 2: Automatisk login + +## Hvad du får ud af det + +Du lærer eksplicitte ventetider (`WebDriverWait`) og at udfylde en formular. `login()` skriver e-mail og adgangskode fra miljøvariabler, indsender og venter til timeplanen vises. En forkert adgangskode vises via sidens fejlmeddelelse. + +## Hvor det er i koden + +`src/snack_and_lift/application/session.py` + +## Skærmbillede + +![Trin 2: Automatisk login](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-2.png) + +> Dette skærmbillede kræver en kørsel med en rigtig gym-konto. Vedligeholderen tilføjer det med `--screenshot-dir` (se [Kom i gang](Getting-Started-da)); indtil da mangler filen `docs/images/step-2.png`, og billedet ovenfor vises ikke. + +[Forrige: 1](Step-1-da) · [Forside](Home-da) · [Næste: 3](Step-3-da) diff --git a/docs/wiki/Step-2-ms.md b/docs/wiki/Step-2-ms.md new file mode 100644 index 0000000..4fc3d51 --- /dev/null +++ b/docs/wiki/Step-2-ms.md @@ -0,0 +1,19 @@ +[English](Step-2) · [Dansk](Step-2-da) · **Bahasa Melayu** + +# Langkah 2: Log masuk automatik + +## Apa yang anda peroleh + +Anda belajar menunggu secara eksplisit (`WebDriverWait`) dan mengisi borang. `login()` menaip e-mel dan kata laluan daripada pemboleh ubah persekitaran, menghantar, dan menunggu sehingga jadual kelas dipaparkan. Kata laluan salah dilaporkan melalui mesej ralat laman. + +## Di mana dalam kod + +`src/snack_and_lift/application/session.py` + +## Tangkapan skrin + +![Langkah 2: Log masuk automatik](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-2.png) + +> Tangkapan skrin ini memerlukan larian dengan akaun gim sebenar. Penyelenggara menambahnya dengan `--screenshot-dir` (lihat [Mula menggunakan](Getting-Started-ms)); sehingga itu fail `docs/images/step-2.png` tiada dan imej di atas tidak dipaparkan. + +[Sebelumnya: 1](Step-1-ms) · [Utama](Home-ms) · [Seterusnya: 3](Step-3-ms) diff --git a/docs/wiki/Step-2.md b/docs/wiki/Step-2.md new file mode 100644 index 0000000..8cd135d --- /dev/null +++ b/docs/wiki/Step-2.md @@ -0,0 +1,19 @@ +**English** · [Dansk](Step-2-da) · [Bahasa Melayu](Step-2-ms) + +# Step 2: Automated login + +## What you gain + +You learn explicit waits (`WebDriverWait`) and how to fill a form. `login()` types the e-mail and password from environment variables, submits, and waits until the class schedule is shown. A wrong password is reported by the site's error message. + +## Where it is in the code + +`src/snack_and_lift/application/session.py` + +## Screenshot + +![Step 2: Automated login](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-2.png) + +> This screenshot needs a run with a real gym account. The maintainer adds it with `--screenshot-dir` (see [Getting started](Getting-Started)); until then the file `docs/images/step-2.png` is missing and the image above does not show. + +[Previous: 1](Step-1) · [Home](Home) · [Next: 3](Step-3) diff --git a/docs/wiki/Step-3-da.md b/docs/wiki/Step-3-da.md new file mode 100644 index 0000000..9f8da74 --- /dev/null +++ b/docs/wiki/Step-3-da.md @@ -0,0 +1,19 @@ +[English](Step-3) · **Dansk** · [Bahasa Melayu](Step-3-ms) + +# Trin 3: Book næste tirsdagshold + +## Hvad du får ud af det + +Du lærer at finde et element relativt til et andet: næste tirsdags dagsgruppe findes med et XPath-opslag på forfædre, derefter 18-kortet og dets knap. `book_class()` klikker på knappen og venter til teksten ændres. + +## Hvor det er i koden + +`src/snack_and_lift/application/booking.py` + +## Skærmbillede + +![Trin 3: Book næste tirsdagshold](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-3.png) + +> Dette skærmbillede kræver en kørsel med en rigtig gym-konto. Vedligeholderen tilføjer det med `--screenshot-dir` (se [Kom i gang](Getting-Started-da)); indtil da mangler filen `docs/images/step-3.png`, og billedet ovenfor vises ikke. + +[Forrige: 2](Step-2-da) · [Forside](Home-da) · [Næste: 4](Step-4-da) diff --git a/docs/wiki/Step-3-ms.md b/docs/wiki/Step-3-ms.md new file mode 100644 index 0000000..b7398a5 --- /dev/null +++ b/docs/wiki/Step-3-ms.md @@ -0,0 +1,19 @@ +[English](Step-3) · [Dansk](Step-3-da) · **Bahasa Melayu** + +# Langkah 3: Tempah kelas Selasa seterusnya + +## Apa yang anda peroleh + +Anda belajar mencari elemen berdasarkan elemen lain: kumpulan hari Selasa seterusnya dicari dengan carian XPath ancestor, kemudian kad pukul 6 petang dan butangnya. `book_class()` menekan butang dan menunggu teks berubah. + +## Di mana dalam kod + +`src/snack_and_lift/application/booking.py` + +## Tangkapan skrin + +![Langkah 3: Tempah kelas Selasa seterusnya](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-3.png) + +> Tangkapan skrin ini memerlukan larian dengan akaun gim sebenar. Penyelenggara menambahnya dengan `--screenshot-dir` (lihat [Mula menggunakan](Getting-Started-ms)); sehingga itu fail `docs/images/step-3.png` tiada dan imej di atas tidak dipaparkan. + +[Sebelumnya: 2](Step-2-ms) · [Utama](Home-ms) · [Seterusnya: 4](Step-4-ms) diff --git a/docs/wiki/Step-3.md b/docs/wiki/Step-3.md new file mode 100644 index 0000000..bdf475a --- /dev/null +++ b/docs/wiki/Step-3.md @@ -0,0 +1,19 @@ +**English** · [Dansk](Step-3-da) · [Bahasa Melayu](Step-3-ms) + +# Step 3: Book the next Tuesday class + +## What you gain + +You learn to find an element relative to another one: the day group of the next Tuesday is found with an XPath ancestor lookup, then the 6pm card and its button. `book_class()` clicks the button and waits until its text changes. + +## Where it is in the code + +`src/snack_and_lift/application/booking.py` + +## Screenshot + +![Step 3: Book the next Tuesday class](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-3.png) + +> This screenshot needs a run with a real gym account. The maintainer adds it with `--screenshot-dir` (see [Getting started](Getting-Started)); until then the file `docs/images/step-3.png` is missing and the image above does not show. + +[Previous: 2](Step-2) · [Home](Home) · [Next: 4](Step-4) diff --git a/docs/wiki/Step-4-da.md b/docs/wiki/Step-4-da.md new file mode 100644 index 0000000..9c431f7 --- /dev/null +++ b/docs/wiki/Step-4-da.md @@ -0,0 +1,19 @@ +[English](Step-4) · **Dansk** · [Bahasa Melayu](Step-4-ms) + +# Trin 4: Tjek om et hold allerede er booket + +## Hvad du får ud af det + +Du lærer at læse en knaps tilstand før du handler: "Book Class", "Join Waitlist", "Booked" eller "Waitlisted". Et hold der allerede er booket klikkes ikke igen, og botten udskriver en ✓-linje om hvad den gjorde. + +## Hvor det er i koden + +`src/snack_and_lift/domain/rules.py` + +## Skærmbillede + +![Trin 4: Tjek om et hold allerede er booket](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-4.png) + +> Dette skærmbillede kræver en kørsel med en rigtig gym-konto. Vedligeholderen tilføjer det med `--screenshot-dir` (se [Kom i gang](Getting-Started-da)); indtil da mangler filen `docs/images/step-4.png`, og billedet ovenfor vises ikke. + +[Forrige: 3](Step-3-da) · [Forside](Home-da) · [Næste: 5](Step-5-da) diff --git a/docs/wiki/Step-4-ms.md b/docs/wiki/Step-4-ms.md new file mode 100644 index 0000000..512c501 --- /dev/null +++ b/docs/wiki/Step-4-ms.md @@ -0,0 +1,19 @@ +[English](Step-4) · [Dansk](Step-4-da) · **Bahasa Melayu** + +# Langkah 4: Semak sama ada kelas sudah ditempah + +## Apa yang anda peroleh + +Anda belajar membaca keadaan butang sebelum bertindak: "Book Class", "Join Waitlist", "Booked" atau "Waitlisted". Kelas yang sudah ditempah tidak ditekan semula, dan bot mencetak baris ✓ tentang apa yang dilakukannya. + +## Di mana dalam kod + +`src/snack_and_lift/domain/rules.py` + +## Tangkapan skrin + +![Langkah 4: Semak sama ada kelas sudah ditempah](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-4.png) + +> Tangkapan skrin ini memerlukan larian dengan akaun gim sebenar. Penyelenggara menambahnya dengan `--screenshot-dir` (lihat [Mula menggunakan](Getting-Started-ms)); sehingga itu fail `docs/images/step-4.png` tiada dan imej di atas tidak dipaparkan. + +[Sebelumnya: 3](Step-3-ms) · [Utama](Home-ms) · [Seterusnya: 5](Step-5-ms) diff --git a/docs/wiki/Step-4.md b/docs/wiki/Step-4.md new file mode 100644 index 0000000..681d18a --- /dev/null +++ b/docs/wiki/Step-4.md @@ -0,0 +1,19 @@ +**English** · [Dansk](Step-4-da) · [Bahasa Melayu](Step-4-ms) + +# Step 4: Check if a class is already booked + +## What you gain + +You learn to read the state of a button before acting: "Book Class", "Join Waitlist", "Booked" or "Waitlisted". A class that is already booked is not clicked again, and the bot prints a ✓ line that says what it did. + +## Where it is in the code + +`src/snack_and_lift/domain/rules.py` + +## Screenshot + +![Step 4: Check if a class is already booked](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-4.png) + +> This screenshot needs a run with a real gym account. The maintainer adds it with `--screenshot-dir` (see [Getting started](Getting-Started)); until then the file `docs/images/step-4.png` is missing and the image above does not show. + +[Previous: 3](Step-3) · [Home](Home) · [Next: 5](Step-5) diff --git a/docs/wiki/Step-5-da.md b/docs/wiki/Step-5-da.md new file mode 100644 index 0000000..c7f9944 --- /dev/null +++ b/docs/wiki/Step-5-da.md @@ -0,0 +1,19 @@ +[English](Step-5) · **Dansk** · [Bahasa Melayu](Step-5-ms) + +# Trin 5: Tællere og et resumé + +## Hvad du får ud af det + +Du lærer at føre tællere mens en løkke kører og at udskrive en rapport: BOOKING SUMMARY viser nye bookinger, nye ventelisteplaceringer og hold der allerede var booket eller på venteliste. + +## Hvor det er i koden + +`src/snack_and_lift/domain/report.py` + +## Skærmbillede + +![Trin 5: Tællere og et resumé](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-5.png) + +> Dette skærmbillede kræver en kørsel med en rigtig gym-konto. Vedligeholderen tilføjer det med `--screenshot-dir` (se [Kom i gang](Getting-Started-da)); indtil da mangler filen `docs/images/step-5.png`, og billedet ovenfor vises ikke. + +[Forrige: 4](Step-4-da) · [Forside](Home-da) · [Næste: 6](Step-6-da) diff --git a/docs/wiki/Step-5-ms.md b/docs/wiki/Step-5-ms.md new file mode 100644 index 0000000..7f04bab --- /dev/null +++ b/docs/wiki/Step-5-ms.md @@ -0,0 +1,19 @@ +[English](Step-5) · [Dansk](Step-5-da) · **Bahasa Melayu** + +# Langkah 5: Pembilang dan ringkasan + +## Apa yang anda peroleh + +Anda belajar menyimpan pembilang semasa gelung berjalan dan mencetak laporan: BOOKING SUMMARY menyenaraikan tempahan baharu, penyertaan senarai menunggu baharu, serta kelas yang sudah ditempah atau dalam senarai menunggu. + +## Di mana dalam kod + +`src/snack_and_lift/domain/report.py` + +## Tangkapan skrin + +![Langkah 5: Pembilang dan ringkasan](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-5.png) + +> Tangkapan skrin ini memerlukan larian dengan akaun gim sebenar. Penyelenggara menambahnya dengan `--screenshot-dir` (lihat [Mula menggunakan](Getting-Started-ms)); sehingga itu fail `docs/images/step-5.png` tiada dan imej di atas tidak dipaparkan. + +[Sebelumnya: 4](Step-4-ms) · [Utama](Home-ms) · [Seterusnya: 6](Step-6-ms) diff --git a/docs/wiki/Step-5.md b/docs/wiki/Step-5.md new file mode 100644 index 0000000..bd8ce0f --- /dev/null +++ b/docs/wiki/Step-5.md @@ -0,0 +1,19 @@ +**English** · [Dansk](Step-5-da) · [Bahasa Melayu](Step-5-ms) + +# Step 5: Counters and a summary + +## What you gain + +You learn to keep counters while a loop runs and to print a report: the BOOKING SUMMARY lists new bookings, new waitlist entries, and classes that were already booked or waitlisted. + +## Where it is in the code + +`src/snack_and_lift/domain/report.py` + +## Screenshot + +![Step 5: Counters and a summary](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-5.png) + +> This screenshot needs a run with a real gym account. The maintainer adds it with `--screenshot-dir` (see [Getting started](Getting-Started)); until then the file `docs/images/step-5.png` is missing and the image above does not show. + +[Previous: 4](Step-4) · [Home](Home) · [Next: 6](Step-6) diff --git a/docs/wiki/Step-6-da.md b/docs/wiki/Step-6-da.md new file mode 100644 index 0000000..3972aac --- /dev/null +++ b/docs/wiki/Step-6-da.md @@ -0,0 +1,19 @@ +[English](Step-6) · **Dansk** · [Bahasa Melayu](Step-6-ms) + +# Trin 6: Alle tirsdags- og torsdagshold + +## Hvad du får ud af det + +Du lærer at gennemløbe alle matchende elementer: hvert tirsdags- og torsdagshold kl. 18 håndteres, og DETAILED CLASS LIST udskriver hvert hold med dato, tid og resultat (New Booking, New Waitlist, Already Booked, Already Waitlisted). + +## Hvor det er i koden + +`src/snack_and_lift/application/booking.py` + +## Skærmbillede + +![Trin 6: Alle tirsdags- og torsdagshold](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-6.png) + +> Dette skærmbillede kræver en kørsel med en rigtig gym-konto. Vedligeholderen tilføjer det med `--screenshot-dir` (se [Kom i gang](Getting-Started-da)); indtil da mangler filen `docs/images/step-6.png`, og billedet ovenfor vises ikke. + +[Forrige: 5](Step-5-da) · [Forside](Home-da) · [Næste: 7](Step-7-da) diff --git a/docs/wiki/Step-6-ms.md b/docs/wiki/Step-6-ms.md new file mode 100644 index 0000000..340fdba --- /dev/null +++ b/docs/wiki/Step-6-ms.md @@ -0,0 +1,19 @@ +[English](Step-6) · [Dansk](Step-6-da) · **Bahasa Melayu** + +# Langkah 6: Semua kelas Selasa dan Khamis + +## Apa yang anda peroleh + +Anda belajar mengulang semua elemen yang sepadan: setiap kelas Selasa dan Khamis pukul 6 petang diuruskan, dan DETAILED CLASS LIST mencetak setiap kelas dengan tarikh, masa dan hasil (New Booking, New Waitlist, Already Booked, Already Waitlisted). + +## Di mana dalam kod + +`src/snack_and_lift/application/booking.py` + +## Tangkapan skrin + +![Langkah 6: Semua kelas Selasa dan Khamis](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-6.png) + +> Tangkapan skrin ini memerlukan larian dengan akaun gim sebenar. Penyelenggara menambahnya dengan `--screenshot-dir` (lihat [Mula menggunakan](Getting-Started-ms)); sehingga itu fail `docs/images/step-6.png` tiada dan imej di atas tidak dipaparkan. + +[Sebelumnya: 5](Step-5-ms) · [Utama](Home-ms) · [Seterusnya: 7](Step-7-ms) diff --git a/docs/wiki/Step-6.md b/docs/wiki/Step-6.md new file mode 100644 index 0000000..22f4b1b --- /dev/null +++ b/docs/wiki/Step-6.md @@ -0,0 +1,19 @@ +**English** · [Dansk](Step-6-da) · [Bahasa Melayu](Step-6-ms) + +# Step 6: Every Tuesday and Thursday class + +## What you gain + +You learn to loop over all matching elements: every Tuesday and Thursday 6pm class is handled, and the DETAILED CLASS LIST prints each class with its date, time and result (New Booking, New Waitlist, Already Booked, Already Waitlisted). + +## Where it is in the code + +`src/snack_and_lift/application/booking.py` + +## Screenshot + +![Step 6: Every Tuesday and Thursday class](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-6.png) + +> This screenshot needs a run with a real gym account. The maintainer adds it with `--screenshot-dir` (see [Getting started](Getting-Started)); until then the file `docs/images/step-6.png` is missing and the image above does not show. + +[Previous: 5](Step-5) · [Home](Home) · [Next: 7](Step-7) diff --git a/docs/wiki/Step-7-da.md b/docs/wiki/Step-7-da.md new file mode 100644 index 0000000..31307db --- /dev/null +++ b/docs/wiki/Step-7-da.md @@ -0,0 +1,19 @@ +[English](Step-7) · **Dansk** · [Bahasa Melayu](Step-7-ms) + +# Trin 7: Bekræft på siden My Bookings + +## Hvad du får ud af det + +Du lærer at kontrollere dit eget arbejde fra en anden kilde: `get_my_bookings()` læser siden My Bookings (bookinger og venteliste) og `verify_bookings()` sammenligner med det botten gjorde. Resultatet er SUCCESS eller MISMATCH (exitkode 3). + +## Hvor det er i koden + +`src/snack_and_lift/application/verification.py` + +## Skærmbillede + +![Trin 7: Bekræft på siden My Bookings](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-7.png) + +> Dette skærmbillede kræver en kørsel med en rigtig gym-konto. Vedligeholderen tilføjer det med `--screenshot-dir` (se [Kom i gang](Getting-Started-da)); indtil da mangler filen `docs/images/step-7.png`, og billedet ovenfor vises ikke. + +[Forrige: 6](Step-6-da) · [Forside](Home-da) · [Næste: 8](Step-8-da) diff --git a/docs/wiki/Step-7-ms.md b/docs/wiki/Step-7-ms.md new file mode 100644 index 0000000..e51acb5 --- /dev/null +++ b/docs/wiki/Step-7-ms.md @@ -0,0 +1,19 @@ +[English](Step-7) · [Dansk](Step-7-da) · **Bahasa Melayu** + +# Langkah 7: Sahkan di halaman My Bookings + +## Apa yang anda peroleh + +Anda belajar menyemak kerja sendiri daripada sumber kedua: `get_my_bookings()` membaca halaman My Bookings (tempahan dan senarai menunggu) dan `verify_bookings()` membandingkannya dengan apa yang dilakukan bot. Hasilnya SUCCESS atau MISMATCH (kod keluar 3). + +## Di mana dalam kod + +`src/snack_and_lift/application/verification.py` + +## Tangkapan skrin + +![Langkah 7: Sahkan di halaman My Bookings](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-7.png) + +> Tangkapan skrin ini memerlukan larian dengan akaun gim sebenar. Penyelenggara menambahnya dengan `--screenshot-dir` (lihat [Mula menggunakan](Getting-Started-ms)); sehingga itu fail `docs/images/step-7.png` tiada dan imej di atas tidak dipaparkan. + +[Sebelumnya: 6](Step-6-ms) · [Utama](Home-ms) · [Seterusnya: 8](Step-8-ms) diff --git a/docs/wiki/Step-7.md b/docs/wiki/Step-7.md new file mode 100644 index 0000000..ef4555f --- /dev/null +++ b/docs/wiki/Step-7.md @@ -0,0 +1,19 @@ +**English** · [Dansk](Step-7-da) · [Bahasa Melayu](Step-7-ms) + +# Step 7: Verify on the My Bookings page + +## What you gain + +You learn to check your own work from a second source: `get_my_bookings()` reads the My Bookings page (bookings and waitlist entries) and `verify_bookings()` compares it with what the bot did. The result is SUCCESS or MISMATCH (exit code 3). + +## Where it is in the code + +`src/snack_and_lift/application/verification.py` + +## Screenshot + +![Step 7: Verify on the My Bookings page](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-7.png) + +> This screenshot needs a run with a real gym account. The maintainer adds it with `--screenshot-dir` (see [Getting started](Getting-Started)); until then the file `docs/images/step-7.png` is missing and the image above does not show. + +[Previous: 6](Step-6) · [Home](Home) · [Next: 8](Step-8) diff --git a/docs/wiki/Step-8-da.md b/docs/wiki/Step-8-da.md new file mode 100644 index 0000000..05fcacb --- /dev/null +++ b/docs/wiki/Step-8-da.md @@ -0,0 +1,19 @@ +[English](Step-8) · **Dansk** · [Bahasa Melayu](Step-8-ms) + +# Trin 8: Kvalitetssikring med tidsrejse + +## Hvad du får ud af det + +Du lærer at datoer er den almindelige fejlkilde: sidens admin-knap "advance 3 days" flytter dens ur. Botten læser dagsetiketterne ("Today", "Tomorrow", "Thu, Aug 14") i stedet for at antage en dato, så den også virker efter et tidshop. + +## Hvor det er i koden + +`src/snack_and_lift/domain/day_label.py` + +## Skærmbillede + +![Trin 8: Kvalitetssikring med tidsrejse](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-8.png) + +> Dette skærmbillede kræver en kørsel med en rigtig gym-konto. Vedligeholderen tilføjer det med `--screenshot-dir` (se [Kom i gang](Getting-Started-da)); indtil da mangler filen `docs/images/step-8.png`, og billedet ovenfor vises ikke. + +[Forrige: 7](Step-7-da) · [Forside](Home-da) · [Næste: 9](Step-9-da) diff --git a/docs/wiki/Step-8-ms.md b/docs/wiki/Step-8-ms.md new file mode 100644 index 0000000..96875e3 --- /dev/null +++ b/docs/wiki/Step-8-ms.md @@ -0,0 +1,19 @@ +[English](Step-8) · [Dansk](Step-8-da) · **Bahasa Melayu** + +# Langkah 8: Jaminan kualiti dengan perjalanan masa + +## Apa yang anda peroleh + +Anda belajar bahawa tarikh ialah punca pepijat biasa: kawalan admin laman "advance 3 days" menggerakkan jamnya. Bot membaca label hari ("Today", "Tomorrow", "Thu, Aug 14") dan bukannya menganggap tarikh, jadi ia berfungsi selepas lompatan masa juga. + +## Di mana dalam kod + +`src/snack_and_lift/domain/day_label.py` + +## Tangkapan skrin + +![Langkah 8: Jaminan kualiti dengan perjalanan masa](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-8.png) + +> Tangkapan skrin ini memerlukan larian dengan akaun gim sebenar. Penyelenggara menambahnya dengan `--screenshot-dir` (lihat [Mula menggunakan](Getting-Started-ms)); sehingga itu fail `docs/images/step-8.png` tiada dan imej di atas tidak dipaparkan. + +[Sebelumnya: 7](Step-7-ms) · [Utama](Home-ms) · [Seterusnya: 9](Step-9-ms) diff --git a/docs/wiki/Step-8.md b/docs/wiki/Step-8.md new file mode 100644 index 0000000..cfaf290 --- /dev/null +++ b/docs/wiki/Step-8.md @@ -0,0 +1,19 @@ +**English** · [Dansk](Step-8-da) · [Bahasa Melayu](Step-8-ms) + +# Step 8: Time travel quality assurance + +## What you gain + +You learn that dates are the usual bug: the site's admin control "advance 3 days" moves its clock. The bot reads the day labels ("Today", "Tomorrow", "Thu, Aug 14") instead of assuming a date, so it works after a time jump too. + +## Where it is in the code + +`src/snack_and_lift/domain/day_label.py` + +## Screenshot + +![Step 8: Time travel quality assurance](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-8.png) + +> This screenshot needs a run with a real gym account. The maintainer adds it with `--screenshot-dir` (see [Getting started](Getting-Started)); until then the file `docs/images/step-8.png` is missing and the image above does not show. + +[Previous: 7](Step-7) · [Home](Home) · [Next: 9](Step-9) diff --git a/docs/wiki/Step-9-da.md b/docs/wiki/Step-9-da.md new file mode 100644 index 0000000..aea80b1 --- /dev/null +++ b/docs/wiki/Step-9-da.md @@ -0,0 +1,19 @@ +[English](Step-9) · **Dansk** · [Bahasa Melayu](Step-9-ms) + +# Trin 9: Robusthed mod netværksfejl + +## Hvad du får ud af det + +Du lærer at prøve igen: `retry(func, retries=7, description=None)` gentager et kald der kaster en fejl, venter mellem forsøgene, logger en advarsel og kaster RetriesExhaustedError til sidst. `login()`, `book_class()` og `get_my_bookings()` er pakket ind i den, så en side der taber forespørgsler ikke stopper kørslen. + +## Hvor det er i koden + +`src/snack_and_lift/application/retry.py` + +## Skærmbillede + +![Trin 9: Robusthed mod netværksfejl](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-9.png) + +> Dette skærmbillede kræver en kørsel med en rigtig gym-konto. Vedligeholderen tilføjer det med `--screenshot-dir` (se [Kom i gang](Getting-Started-da)); indtil da mangler filen `docs/images/step-9.png`, og billedet ovenfor vises ikke. + +[Forrige: 8](Step-8-da) · [Forside](Home-da) diff --git a/docs/wiki/Step-9-ms.md b/docs/wiki/Step-9-ms.md new file mode 100644 index 0000000..a0bb96b --- /dev/null +++ b/docs/wiki/Step-9-ms.md @@ -0,0 +1,19 @@ +[English](Step-9) · [Dansk](Step-9-da) · **Bahasa Melayu** + +# Langkah 9: Ketahanan terhadap kegagalan rangkaian + +## Apa yang anda peroleh + +Anda belajar mencuba semula: `retry(func, retries=7, description=None)` mengulang panggilan yang gagal, menunggu antara percubaan, mencatat amaran dan melempar RetriesExhaustedError di akhir. `login()`, `book_class()` dan `get_my_bookings()` dibalut dengannya, jadi laman yang menjatuhkan permintaan tidak menghentikan larian. + +## Di mana dalam kod + +`src/snack_and_lift/application/retry.py` + +## Tangkapan skrin + +![Langkah 9: Ketahanan terhadap kegagalan rangkaian](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-9.png) + +> Tangkapan skrin ini memerlukan larian dengan akaun gim sebenar. Penyelenggara menambahnya dengan `--screenshot-dir` (lihat [Mula menggunakan](Getting-Started-ms)); sehingga itu fail `docs/images/step-9.png` tiada dan imej di atas tidak dipaparkan. + +[Sebelumnya: 8](Step-8-ms) · [Utama](Home-ms) diff --git a/docs/wiki/Step-9.md b/docs/wiki/Step-9.md new file mode 100644 index 0000000..040a92e --- /dev/null +++ b/docs/wiki/Step-9.md @@ -0,0 +1,19 @@ +**English** · [Dansk](Step-9-da) · [Bahasa Melayu](Step-9-ms) + +# Step 9: Resilience against network failures + +## What you gain + +You learn to retry: `retry(func, retries=7, description=None)` repeats a call that raises, waits between attempts, logs a warning and raises RetriesExhaustedError at the end. `login()`, `book_class()` and `get_my_bookings()` are wrapped with it, so a site that drops requests does not stop the run. + +## Where it is in the code + +`src/snack_and_lift/application/retry.py` + +## Screenshot + +![Step 9: Resilience against network failures](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/raw/branch/main/docs/images/step-9.png) + +> This screenshot needs a run with a real gym account. The maintainer adds it with `--screenshot-dir` (see [Getting started](Getting-Started)); until then the file `docs/images/step-9.png` is missing and the image above does not show. + +[Previous: 8](Step-8) · [Home](Home) diff --git a/docs/wiki/Troubleshooting-da.md b/docs/wiki/Troubleshooting-da.md new file mode 100644 index 0000000..241aa02 --- /dev/null +++ b/docs/wiki/Troubleshooting-da.md @@ -0,0 +1,12 @@ +[English](Troubleshooting) · **Dansk** · [Bahasa Melayu](Troubleshooting-ms) + +# Fejlfinding + +| Symptom | Årsag og løsning | +| --- | --- | +| Exitkode 2 | `SNACK_AND_LIFT_EMAIL` eller `SNACK_AND_LIFT_PASSWORD` er ikke sat. | +| Login fejler 7 gange, derefter exit 1 | Forkert e-mail eller adgangskode, eller kontoen findes ikke i denne `chrome_profile` (siden gemmer konti i browseren). Opret den igen med `--keep-open`. | +| Exitkode 3 og MISMATCH | Siden My Bookings viser ikke det botten bookede. Kør igen; tjek om et hold var fyldt. | +| Advarsler "attempt 2 of 7" | Sidens fejlrate er slået til; det er retry der arbejder (trin 9). | +| Chrome advarer om adgangskoden | Chrome markerer svage adgangskoder som `12346`; vælg en anden. | +| Intet vindue i Docker | Containeren er headless med vilje; brug `--screenshot-dir`. | diff --git a/docs/wiki/Troubleshooting-ms.md b/docs/wiki/Troubleshooting-ms.md new file mode 100644 index 0000000..f8fbfd8 --- /dev/null +++ b/docs/wiki/Troubleshooting-ms.md @@ -0,0 +1,12 @@ +[English](Troubleshooting) · [Dansk](Troubleshooting-da) · **Bahasa Melayu** + +# Menyelesaikan masalah + +| Gejala | Punca dan penyelesaian | +| --- | --- | +| Kod keluar 2 | `SNACK_AND_LIFT_EMAIL` atau `SNACK_AND_LIFT_PASSWORD` tidak ditetapkan. | +| Log masuk gagal 7 kali, kemudian keluar 1 | E-mel atau kata laluan salah, atau akaun tiada dalam `chrome_profile` ini (laman menyimpan akaun dalam pelayar). Daftar semula dengan `--keep-open`. | +| Kod keluar 3 dan MISMATCH | Halaman My Bookings tidak menyenaraikan apa yang ditempah bot. Jalankan semula; semak sama ada kelas penuh. | +| Amaran "attempt 2 of 7" | Kadar kegagalan laman dihidupkan; ini retry sedang berfungsi (langkah 9). | +| Chrome memberi amaran tentang kata laluan | Chrome menandakan kata laluan lemah seperti `12346`; pilih yang lain. | +| Tiada tetingkap dalam Docker | Bekas ini tanpa kepala (headless) secara sengaja; gunakan `--screenshot-dir`. | diff --git a/docs/wiki/Troubleshooting.md b/docs/wiki/Troubleshooting.md new file mode 100644 index 0000000..bc785b8 --- /dev/null +++ b/docs/wiki/Troubleshooting.md @@ -0,0 +1,12 @@ +**English** · [Dansk](Troubleshooting-da) · [Bahasa Melayu](Troubleshooting-ms) + +# Troubleshooting + +| Symptom | Cause and fix | +| --- | --- | +| Exit code 2 | `SNACK_AND_LIFT_EMAIL` or `SNACK_AND_LIFT_PASSWORD` is not set. | +| Login fails 7 times, then exit 1 | Wrong e-mail or password, or the account is not in this `chrome_profile` (the site keeps accounts in the browser). Register again with `--keep-open`. | +| Exit code 3 and MISMATCH | The My Bookings page does not list what the bot booked. Run again; check whether a class was full. | +| Warnings "attempt 2 of 7" | The site's failure rate is on; this is the retry at work (step 9). | +| Chrome warns about the password | Chrome flags weak passwords such as `12346`; choose another. | +| No window in Docker | The container is headless by design; use `--screenshot-dir`. | diff --git a/docs/wiki/_Footer.md b/docs/wiki/_Footer.md new file mode 100644 index 0000000..d736297 --- /dev/null +++ b/docs/wiki/_Footer.md @@ -0,0 +1 @@ +[Repository](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift) · [Snack and Lift](https://appbrewery.github.io/gym/) · AGPL-3.0 diff --git a/docs/wiki/_Sidebar.md b/docs/wiki/_Sidebar.md new file mode 100644 index 0000000..73c38b5 --- /dev/null +++ b/docs/wiki/_Sidebar.md @@ -0,0 +1,11 @@ +**English** +- [Home](Home) · [Getting started](Getting-Started) · [Troubleshooting](Troubleshooting) +- [1](Step-1) · [2](Step-2) · [3](Step-3) · [4](Step-4) · [5](Step-5) · [6](Step-6) · [7](Step-7) · [8](Step-8) · [9](Step-9) + +**Dansk** +- [Forside](Home-da) · [Kom i gang](Getting-Started-da) · [Fejlfinding](Troubleshooting-da) +- [1](Step-1-da) · [2](Step-2-da) · [3](Step-3-da) · [4](Step-4-da) · [5](Step-5-da) · [6](Step-6-da) · [7](Step-7-da) · [8](Step-8-da) · [9](Step-9-da) + +**Bahasa Melayu** +- [Utama](Home-ms) · [Mula menggunakan](Getting-Started-ms) · [Menyelesaikan masalah](Troubleshooting-ms) +- [1](Step-1-ms) · [2](Step-2-ms) · [3](Step-3-ms) · [4](Step-4-ms) · [5](Step-5-ms) · [6](Step-6-ms) · [7](Step-7-ms) · [8](Step-8-ms) · [9](Step-9-ms) -- 2.54.0 From 08ced00f62b9f7e26c6c7f1521d748e86cf3e8e1 Mon Sep 17 00:00:00 2001 From: Jens Tirsvad Nielsen Date: Wed, 28 Oct 2026 18:20:49 +0800 Subject: [PATCH 2/2] Resolve pending commit links --- docs/sqa/reviews/rc-022-workflows-mil-008.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/sqa/reviews/rc-022-workflows-mil-008.md b/docs/sqa/reviews/rc-022-workflows-mil-008.md index 779ab99..a7fb2db 100644 --- a/docs/sqa/reviews/rc-022-workflows-mil-008.md +++ b/docs/sqa/reviews/rc-022-workflows-mil-008.md @@ -9,7 +9,7 @@ ## Version History | Date | Status | Author | Reviewer | Change | Commit | | --- | --- | --- | --- | --- | --- | -| 2026-10-28 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S02 | Review record, the workflows publish-wiki.yml and sync-milestones.yml of MIL-008 task 5 | pending | +| 2026-10-28 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S02 | Review record, the workflows publish-wiki.yml and sync-milestones.yml of MIL-008 task 5 | [0301fd2] | --- @@ -66,3 +66,4 @@ Go-with-conditions - the two workflows are the framework's templates, copied int [MIL-008]: ../../milestones/mil-008-documentation.md [QC-WF-001]: ../../../framework/qc/code/qc-workflow.md +[0301fd2]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/049-snack-and-lift/commit/0301fd2f0bc22a26ee8d71ec41dab2bce0d38dc3 -- 2.54.0