MIL-003 Documentation and wiki #23

Merged
Tirsvad merged 2 commits from mil-003-documentation into main 2026-10-28 09:25:09 +01:00
17 changed files with 437 additions and 2 deletions
Showing only changes of commit 9565ebe66d - Show all commits
+22
View File
@@ -28,6 +28,19 @@ The code automates the three steps of the lecture:
| `docs/` | Project documents, screenshots and the wiki in English, Danish and Bahasa Malaysia | | `docs/` | Project documents, screenshots and the wiki in English, Danish and Bahasa Malaysia |
| `Doxyfile` | Configuration for the Doxygen API documentation | | `Doxyfile` | Configuration for the Doxygen API documentation |
### Screenshots of the lecture steps
Taken in a Docker container with headless Chromium.
| Step | Screenshot |
| --- | --- |
| 1. Click the link "Content portals" | ![Step 1][img-step-1] |
| 2. Search for "Python" and press Enter | ![Step 2][img-step-2] |
| 3. Fill out the form, before Sign Up | ![Step 3, filled][img-step-3-filled] |
| 3. After Sign Up (the demo page rejects the default example.com address; pass your own with `--email`) | ![Step 3, signed up][img-step-3-signed-up] |
What each step teaches is explained in the wiki: [English][wiki-en], [Dansk][wiki-da], [Bahasa Malaysia][wiki-ms].
## 📋 Requirements ## 📋 Requirements
- Python 3.13 or newer, with `venv` — the language and the isolated environment. - Python 3.13 or newer, with `venv` — the language and the isolated environment.
@@ -123,6 +136,7 @@ The documents a newcomer needs, in reading order.
| [Project Plan][PP-001] | The gateways and their schedule | | [Project Plan][PP-001] | The gateways and their schedule |
| [Milestones][milestones] | One document per gateway: Go/No-Go criteria and tasks | | [Milestones][milestones] | One document per gateway: Go/No-Go criteria and tasks |
| [Artifact registry][registry] | Where each artifact type lives, the next version, the PO language and domain | | [Artifact registry][registry] | Where each artifact type lives, the next version, the PO language and domain |
| [Wiki pages (docs/wiki)][wiki-dir] | The lecture steps explained, in three languages |
| [Traceability matrix][TM-001] | How the artifacts link and when each was last reviewed | | [Traceability matrix][TM-001] | How the artifacts link and when each was last reviewed |
| [Framework README][framework-readme] | The framework this project uses | | [Framework README][framework-readme] | The framework this project uses |
| [Framework changelog][framework-changelog] | What changed in each framework release | | [Framework changelog][framework-changelog] | What changed in each framework release |
@@ -131,6 +145,13 @@ The documents a newcomer needs, in reading order.
[repository]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/048-fill-out-form [repository]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/048-fill-out-form
[documentation]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/048-fill-out-form/wiki [documentation]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/048-fill-out-form/wiki
[wiki-en]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/048-fill-out-form/wiki/Home
[wiki-da]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/048-fill-out-form/wiki/Home-da
[wiki-ms]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/048-fill-out-form/wiki/Home-ms
[img-step-1]: ./docs/images/step-1-click-link.png
[img-step-2]: ./docs/images/step-2-search.png
[img-step-3-filled]: ./docs/images/step-3-form-filled.png
[img-step-3-signed-up]: ./docs/images/step-3-form-signed-up.png
[issues]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/048-fill-out-form/issues [issues]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/048-fill-out-form/issues
[license]: ./LICENSE [license]: ./LICENSE
[agents]: ./AGENTS.md [agents]: ./AGENTS.md
@@ -139,6 +160,7 @@ The documents a newcomer needs, in reading order.
[PP-001]: ./docs/project-plan.md [PP-001]: ./docs/project-plan.md
[milestones]: ./docs/milestones/ [milestones]: ./docs/milestones/
[registry]: ./docs/artifact-registry.md [registry]: ./docs/artifact-registry.md
[wiki-dir]: ./docs/wiki/
[TM-001]: ./docs/sqa/traceability-matrix.md [TM-001]: ./docs/sqa/traceability-matrix.md
[framework-readme]: ./framework/README.md [framework-readme]: ./framework/README.md
[framework-changelog]: ./framework/CHANGELOG.md [framework-changelog]: ./framework/CHANGELOG.md
+1 -1
View File
@@ -16,7 +16,7 @@ document of a type. `Primary File` may contain a glob (e.g.
| PP | Project Plan | docs/project-plan.md | 002 | | PP | Project Plan | docs/project-plan.md | 002 |
| MIL | Milestone / Gateway | docs/milestones/*.md | 004 | | MIL | Milestone / Gateway | docs/milestones/*.md | 004 |
| ADR | Architecture Decision Record | docs/adr/adr-NNNN-*.md | 0002 | | ADR | Architecture Decision Record | docs/adr/adr-NNNN-*.md | 0002 |
| RC | SQA Review Record | docs/sqa/reviews/rc-*.md | 011 | | RC | SQA Review Record | docs/sqa/reviews/rc-*.md | 012 |
| TM | Traceability Matrix | docs/sqa/traceability-matrix.md | 002 | | TM | Traceability Matrix | docs/sqa/traceability-matrix.md | 002 |
## Languages ## Languages
+50
View File
@@ -0,0 +1,50 @@
# SQA Review Record: wiki and README (MIL-003)
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-011 |
| CrossReference | [MIL-003] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-28 | Accepted | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | pending |
---
## Artifact Under Review
- Instance reviewed: [MIL-003]
- Checklist used: none exists for a wiki; the rules of `framework/process/wiki.md` and the Go/No-Go criteria of [MIL-003] are used
- Scope: full review of `docs/wiki/` and `README.md`
- Language and domain: en, da and ms wiki; `n/a` (a wiki is not an artifact with Language and Domain rows)
- Language reviewer: none; the reviewer is not a native speaker of Danish or Bahasa Malaysia, so the translations are not independently verified (see Action Items)
- Mode: autonomous, not independent (reviewer: AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | English is the authoritative text and each translation follows it page by page | Pass | The da and ms pages have the same sections in the same order as the English page. |
| 2 | Every English page exists in the PO language and in the added languages, with the same page set | Pass | Home, Step-1-Link-Click, Step-2-Search and Step-3-Form exist as `.md`, `-da.md` and `-ms.md`; the PO language is English, so da and ms are additions (checked with ls). |
| 3 | Each page starts with the language line, and `_Sidebar.md` lists every language | Pass | All 12 pages start with the language line linking the other two languages; `_Sidebar.md` lists English, Dansk and Bahasa Malaysia. |
| 4 | Code blocks, commands, file names and IDs stay in English | Pass | Code, commands and `constants.py` names are unchanged in all languages. |
| 5 | The PO language is the one in the registry; the wiki does not decide it | Pass | Registry PO language is en; no wiki page changes it. |
| 6 | Each page explains what was gained in its lecture step and shows the screenshot (MIL-003 criteria 3 and 4) | Pass | Each step page has the sections lecture, code, what the browser shows (image) and what we gained, in three languages. |
| 7 | The README shows one screenshot per lecture step and `check-readme.sh` passes (MIL-003 criterion 1) | Pass | README has a screenshots table with four images (step 3 twice); `check-readme.sh` reports only a finding about the framework README, not the project README. |
| 8 | Internal links resolve | Pass | A script checked every page link against the files; none are broken. Image URLs point to the raw files of `main` and work once this branch is merged. |
## Overall Verdict
Go — all criteria pass. The translations follow the English text but a native speaker has not read them.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| Read the Danish and Bahasa Malaysia pages and correct wording | S01 | 2026-11-04 |
---
[MIL-003]: ../../milestones/mil-003-documentation.md
+2 -1
View File
@@ -28,7 +28,7 @@ updated whenever an artifact instance is created or reviewed.
| [PP-001] | PP | en | it | [BC-001], [SA-001] | [MIL-001], [MIL-002], [MIL-003] | [RC-003] | | [PP-001] | PP | en | it | [BC-001], [SA-001] | [MIL-001], [MIL-002], [MIL-003] | [RC-003] |
| [MIL-001] | MIL | en | it | [PP-001] | [MIL-002], [ADR-0001] | [RC-004], [RC-008] (code) | | [MIL-001] | MIL | en | it | [PP-001] | [MIL-002], [ADR-0001] | [RC-004], [RC-008] (code) |
| [MIL-002] | MIL | en | it | [MIL-001] | [MIL-003] | [RC-010], [RC-009] (code) | | [MIL-002] | MIL | en | it | [MIL-001] | [MIL-003] | [RC-010], [RC-009] (code) |
| [MIL-003] | MIL | en | it | [MIL-002] | - | [RC-006] | | [MIL-003] | MIL | en | it | [MIL-002] | - | [RC-006], [RC-011] (wiki) |
| [ADR-0001] | ADR | - | - | [BC-001], [MIL-001] | - | [RC-007] | | [ADR-0001] | ADR | - | - | [BC-001], [MIL-001] | - | [RC-007] |
## Concern Coverage ## Concern Coverage
@@ -73,3 +73,4 @@ updated whenever an artifact instance is created or reviewed.
[e1a3d8d]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/048-fill-out-form/commit/e1a3d8d304d4b6ece1a3f95ee02b597e30a97520 [e1a3d8d]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/048-fill-out-form/commit/e1a3d8d304d4b6ece1a3f95ee02b597e30a97520
[RC-009]: ./reviews/rc-009-code-mil-002.md [RC-009]: ./reviews/rc-009-code-mil-002.md
[RC-010]: ./reviews/rc-010-mil-002-form-automation.md [RC-010]: ./reviews/rc-010-mil-002-form-automation.md
[RC-011]: ./reviews/rc-011-wiki.md
+28
View File
@@ -0,0 +1,28 @@
[English](Home) · **Dansk** · [Bahasa Malaysia](Home-ms)
# Dag 48: Udfyld en formular med Selenium
Dette projekt løser lektionen for dag 48 i Udemys "100 Days of Code: The Complete Python Pro Bootcamp". Lektionen viser, hvordan Selenium WebDriver arbejder med en side: klikke på elementer, skrive i felter, sende specialtaster og udfylde en formular.
## Hvad hvert trin giver dig
| Trin | Emne i lektionen | Funktion | Det lærer du |
| --- | --- | --- | --- |
| 1 | Klik på et link, find det via dets tekst | `click_link_by_text` | At navigere uden musen |
| 2 | Skriv i et felt og send Enter-tasten | `search_for` | At udfylde et felt og sende med en specialtast |
| 3 | Udfordring: udfyld en formular og klik på knappen | `fill_out_form` | At kombinere selektorer, indtastning og klik |
- [Trin 1: Klik på et link](Step-1-Link-Click-da)
- [Trin 2: Søg](Step-2-Search-da)
- [Trin 3: Formularen](Step-3-Form-da)
## Kør det
```bash
python -m venv .venv
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
python -m fill_out_form
```
Repositoriets README har den fulde vejledning, testene og Docker-kørslen, som aldrig rører din skærm.
+28
View File
@@ -0,0 +1,28 @@
[English](Home) · [Dansk](Home-da) · **Bahasa Malaysia**
# Hari 48: Isi borang dengan Selenium
Projek ini menyelesaikan pelajaran hari ke-48 dalam "100 Days of Code: The Complete Python Pro Bootcamp" di Udemy. Pelajaran ini menunjukkan bagaimana Selenium WebDriver berinteraksi dengan sebuah laman: mengklik elemen, menaip ke dalam medan input, menghantar kekunci khas dan mengisi borang.
## Apa yang anda peroleh daripada setiap langkah
| Langkah | Topik pelajaran | Fungsi | Apa yang anda peroleh |
| --- | --- | --- | --- |
| 1 | Klik pautan, cari melalui teksnya | `click_link_by_text` | Menavigasi tanpa tetikus |
| 2 | Taip ke dalam input dan hantar kekunci Enter | `search_for` | Mengisi input dan menghantar dengan kekunci khas |
| 3 | Cabaran: isi borang dan klik butang | `fill_out_form` | Menggabungkan pemilih, penaipan dan klik |
- [Langkah 1: Klik pautan](Step-1-Link-Click-ms)
- [Langkah 2: Cari](Step-2-Search-ms)
- [Langkah 3: Borang](Step-3-Form-ms)
## Jalankan
```bash
python -m venv .venv
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
python -m fill_out_form
```
README repositori mengandungi arahan lengkap, ujian dan larian Docker yang tidak pernah menyentuh desktop anda.
+28
View File
@@ -0,0 +1,28 @@
**English** · [Dansk](Home-da) · [Bahasa Malaysia](Home-ms)
# Day 48: Fill out a form with Selenium
This project solves the Day 48 lecture of Udemy's "100 Days of Code: The Complete Python Pro Bootcamp". The lecture shows how Selenium WebDriver interacts with a page: clicking elements, typing into inputs, sending special keys and filling out a form.
## What each lecture step gives you
| Step | Lecture topic | Function | What you gain |
| --- | --- | --- | --- |
| 1 | Click a link, find it by its text | `click_link_by_text` | Navigate without the mouse |
| 2 | Type into an input and send the Enter key | `search_for` | Fill an input and submit with a special key |
| 3 | Challenge: fill out a form and click the button | `fill_out_form` | Combine selectors, typing and clicking |
- [Step 1: Click a link](Step-1-Link-Click)
- [Step 2: Search](Step-2-Search)
- [Step 3: The form](Step-3-Form)
## Run it
```bash
python -m venv .venv
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
python -m fill_out_form
```
The README of the repository has the full instructions, the tests and the Docker run that never touches your desktop.
+26
View File
@@ -0,0 +1,26 @@
[English](Step-1-Link-Click) · **Dansk** · [Bahasa Malaysia](Step-1-Link-Click-ms)
# Trin 1: Klik på et link via dets tekst
## Lektionen
Efter en gennemgang af, hvordan man finder elementer, viser lektionen, at et anchor-tag kan klikkes med metoden `.click()`, så browseren navigerer af sig selv i stedet for med et museklik. Derefter vises en genvej til links: find linket via den tekst, det viser, her "Content portals".
## Koden
```python
def click_link_by_text(browser, link_text=LINK_TEXT_CONTENT_PORTALS):
browser.find_element(BY_LINK_TEXT, link_text).click()
```
`BY_LINK_TEXT` har samme værdi som Selenium's `By.LINK_TEXT`; en enhedstest sikrer det. Linkteksten står i `constants.py`.
## Hvad browseren viser
![Wikipedia-siden "Contents/Portals" efter klikket](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/048-fill-out-form/raw/branch/main/docs/images/step-1-click-link.png)
## Det lærte vi
- Et link er et element som alle andre: find det, og kald `.click()`.
- `By.LINK_TEXT` finder et link via den synlige tekst, hvilket er enklere end en CSS-selektor.
- Efter klikket er browseren på en ny side; næste trin starter derfra.
+26
View File
@@ -0,0 +1,26 @@
[English](Step-1-Link-Click) · [Dansk](Step-1-Link-Click-da) · **Bahasa Malaysia**
# Langkah 1: Klik pautan melalui teksnya
## Pelajaran
Selepas mengulang kaji cara mencari elemen, pelajaran menunjukkan bahawa tag anchor boleh diklik dengan kaedah `.click()`, supaya pelayar bergerak sendiri dan bukan dengan klik tetikus. Kemudian diperkenalkan jalan pintas untuk pautan: cari pautan melalui teks yang dipaparkannya, di sini "Content portals".
## Kod
```python
def click_link_by_text(browser, link_text=LINK_TEXT_CONTENT_PORTALS):
browser.find_element(BY_LINK_TEXT, link_text).click()
```
`BY_LINK_TEXT` mempunyai nilai yang sama dengan `By.LINK_TEXT` Selenium; ujian unit menjaganya. Teks pautan berada dalam `constants.py`.
## Apa yang dipaparkan pelayar
![Laman Wikipedia "Contents/Portals" selepas klik](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/048-fill-out-form/raw/branch/main/docs/images/step-1-click-link.png)
## Apa yang kita peroleh
- Pautan ialah elemen seperti yang lain: cari, kemudian panggil `.click()`.
- `By.LINK_TEXT` mencari pautan melalui teks yang kelihatan, lebih mudah daripada pemilih CSS.
- Selepas klik, pelayar sudah berada di laman baharu; langkah seterusnya bermula dari situ.
+26
View File
@@ -0,0 +1,26 @@
**English** · [Dansk](Step-1-Link-Click-da) · [Bahasa Malaysia](Step-1-Link-Click-ms)
# Step 1: Click a link by its text
## The lecture
After a recap of how to find elements, the lecture shows that an anchor tag can be clicked with the `.click()` method, so the browser navigates by itself instead of by a mouse click. It then introduces a shortcut for links: find the link by the text it displays, here "Content portals".
## The code
```python
def click_link_by_text(browser, link_text=LINK_TEXT_CONTENT_PORTALS):
browser.find_element(BY_LINK_TEXT, link_text).click()
```
`BY_LINK_TEXT` is the same value as Selenium's `By.LINK_TEXT`; a unit test guards that. The link text lives in `constants.py`.
## What the browser shows
![The Wikipedia page "Contents/Portals" after the click](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/048-fill-out-form/raw/branch/main/docs/images/step-1-click-link.png)
## What we gained
- A link is an element like any other: find it, then call `.click()`.
- `By.LINK_TEXT` finds a link by its visible text, which is simpler than a CSS selector.
- After the click the browser has moved to a new page; the next step starts from there.
+28
View File
@@ -0,0 +1,28 @@
[English](Step-2-Search) · **Dansk** · [Bahasa Malaysia](Step-2-Search-ms)
# Trin 2: Skriv i et felt og tryk på Enter
## Lektionen
Lektionen skriver "Python" i Wikipedias søgefelt. Feltet findes via dets `name`-attribut, teksten skrives med `send_keys`, og specialtasten Enter sendes med klassen `Keys` fra `selenium.webdriver.common.keys`, hvilket udfører søgningen.
## Koden
```python
def search_for(browser, term=SEARCH_TERM):
search_input = browser.find_element(BY_NAME, SEARCH_INPUT_NAME)
search_input.send_keys(term)
search_input.send_keys(KEY_ENTER)
```
`KEY_ENTER` har samme værdi som `Keys.ENTER`, også sikret af en enhedstest.
## Hvad browseren viser
![Wikipedia-artiklen "Python" efter søgningen](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/048-fill-out-form/raw/branch/main/docs/images/step-2-search.png)
## Det lærte vi
- `By.NAME` finder et felt via dets `name`-attribut.
- `send_keys` skriver tekst i et felt og sender også specialtaster som Enter.
- Når man sender Enter, udføres en søgning som en person ville gøre det, uden at finde en søgeknap.
+28
View File
@@ -0,0 +1,28 @@
[English](Step-2-Search) · [Dansk](Step-2-Search-da) · **Bahasa Malaysia**
# Langkah 2: Taip ke dalam input dan tekan Enter
## Pelajaran
Pelajaran menaip "Python" ke dalam bar carian Wikipedia. Bar itu dicari melalui atribut `name`, teks ditaip dengan `send_keys`, dan kekunci khas Enter dihantar dengan kelas `Keys` daripada `selenium.webdriver.common.keys`, yang menghantar carian.
## Kod
```python
def search_for(browser, term=SEARCH_TERM):
search_input = browser.find_element(BY_NAME, SEARCH_INPUT_NAME)
search_input.send_keys(term)
search_input.send_keys(KEY_ENTER)
```
`KEY_ENTER` mempunyai nilai yang sama dengan `Keys.ENTER`, juga dijaga oleh ujian unit.
## Apa yang dipaparkan pelayar
![Artikel Wikipedia "Python" selepas carian](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/048-fill-out-form/raw/branch/main/docs/images/step-2-search.png)
## Apa yang kita peroleh
- `By.NAME` mencari input melalui atribut `name`.
- `send_keys` menaip teks ke dalam input dan juga menghantar kekunci khas seperti Enter.
- Menghantar Enter membuat carian seperti yang dilakukan seseorang, tanpa mencari butang carian.
+28
View File
@@ -0,0 +1,28 @@
**English** · [Dansk](Step-2-Search-da) · [Bahasa Malaysia](Step-2-Search-ms)
# Step 2: Type into an input and press Enter
## The lecture
The lecture types "Python" into the Wikipedia search bar. The bar is found by its `name` attribute, text is typed with `send_keys`, and the special Enter key is sent with the `Keys` class from `selenium.webdriver.common.keys`, which submits the search.
## The code
```python
def search_for(browser, term=SEARCH_TERM):
search_input = browser.find_element(BY_NAME, SEARCH_INPUT_NAME)
search_input.send_keys(term)
search_input.send_keys(KEY_ENTER)
```
`KEY_ENTER` is the same value as `Keys.ENTER`, again guarded by a unit test.
## What the browser shows
![The Wikipedia article "Python" after the search](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/048-fill-out-form/raw/branch/main/docs/images/step-2-search.png)
## What we gained
- `By.NAME` finds an input by its `name` attribute.
- `send_keys` types text into an input, and also sends special keys such as Enter.
- Sending Enter submits a search like a person would, without finding a search button.
+37
View File
@@ -0,0 +1,37 @@
[English](Step-3-Form) · **Dansk** · [Bahasa Malaysia](Step-3-Form-ms)
# Trin 3: Udfordring, udfyld en formular
## Lektionen
Udfordringen: udfyld en tilmeldingsformular med fornavn, efternavn og e-mailadresse, og klik derefter på knappen Sign Up. Nogle elementer har intet id eller navn, der er nemt at bruge, så lektionen peger på CSS-selektorer.
## Koden
```python
def fill_out_form(browser, form_data=None, before_submit=None):
data = form_data if form_data is not None else default_form_data()
browser.find_element(BY_CSS_SELECTOR, FIRST_NAME_SELECTOR).send_keys(data.first_name)
browser.find_element(BY_CSS_SELECTOR, LAST_NAME_SELECTOR).send_keys(data.last_name)
browser.find_element(BY_CSS_SELECTOR, EMAIL_SELECTOR).send_keys(data.email)
if before_submit is not None:
before_submit()
browser.find_element(BY_CSS_SELECTOR, SIGN_UP_BUTTON_SELECTOR).click()
```
## Hvad browseren viser
Formularen efter indtastning, før klikket:
![Tilmeldingsformularen udfyldt med Jane, Doe og en e-mailadresse](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/048-fill-out-form/raw/branch/main/docs/images/step-3-form-filled.png)
Siden efter Sign Up. Demosiden kontrollerer e-mailadressen, og standardadressen `jane.doe@example.com` afvises. Kør programmet med din egen adresse (`--email dig@dittdomæne.dk`) for at se succes-siden:
![Demosiden svarer "Uh oh" på standardadressen example.com](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/048-fill-out-form/raw/branch/main/docs/images/step-3-form-signed-up.png)
## Det lærte vi
- En CSS-selektor som `input[name='fName']` finder et element uden id.
- Trin 1 og 2 kombineres her: find, skriv, klik.
- En rigtig side kan svare uventet; skærmbilledet efter klikket viser, hvad der faktisk skete.
- Når selektorer står i `constants.py`, kræver en ændret side én rettelse i stedet for en søgning i koden.
+37
View File
@@ -0,0 +1,37 @@
[English](Step-3-Form) · [Dansk](Step-3-Form-da) · **Bahasa Malaysia**
# Langkah 3: Cabaran, isi borang
## Pelajaran
Cabarannya: isi borang pendaftaran dengan nama pertama, nama akhir dan alamat e-mel, kemudian klik butang Sign Up. Sesetengah elemen tidak mempunyai id atau nama yang mudah digunakan, jadi pelajaran menunjuk kepada pemilih CSS.
## Kod
```python
def fill_out_form(browser, form_data=None, before_submit=None):
data = form_data if form_data is not None else default_form_data()
browser.find_element(BY_CSS_SELECTOR, FIRST_NAME_SELECTOR).send_keys(data.first_name)
browser.find_element(BY_CSS_SELECTOR, LAST_NAME_SELECTOR).send_keys(data.last_name)
browser.find_element(BY_CSS_SELECTOR, EMAIL_SELECTOR).send_keys(data.email)
if before_submit is not None:
before_submit()
browser.find_element(BY_CSS_SELECTOR, SIGN_UP_BUTTON_SELECTOR).click()
```
## Apa yang dipaparkan pelayar
Borang selepas menaip, sebelum klik:
![Borang pendaftaran diisi dengan Jane, Doe dan alamat e-mel](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/048-fill-out-form/raw/branch/main/docs/images/step-3-form-filled.png)
Laman selepas Sign Up. Laman demo memeriksa alamat e-mel, dan alamat lalai `jane.doe@example.com` ditolak. Jalankan program dengan alamat anda sendiri (`--email anda@domainanda.com`) untuk melihat laman berjaya:
![Laman demo menjawab "Uh oh" kepada alamat lalai example.com](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/048-fill-out-form/raw/branch/main/docs/images/step-3-form-signed-up.png)
## Apa yang kita peroleh
- Pemilih CSS seperti `input[name='fName']` mencari elemen yang tiada id.
- Langkah 1 dan 2 digabungkan di sini: cari, taip, klik.
- Laman sebenar boleh menjawab di luar jangkaan; tangkapan skrin selepas klik menunjukkan apa yang benar-benar berlaku.
- Menyimpan pemilih dalam `constants.py` bermakna laman yang berubah hanya memerlukan satu pembetulan, bukan mencari dalam kod.
+37
View File
@@ -0,0 +1,37 @@
**English** · [Dansk](Step-3-Form-da) · [Bahasa Malaysia](Step-3-Form-ms)
# Step 3: Challenge, fill out a form
## The lecture
The challenge: fill out a sign-up form with a first name, last name and email address, then click the Sign Up button. Some elements have no id or name that is easy to use, so the lecture points to CSS selectors.
## The code
```python
def fill_out_form(browser, form_data=None, before_submit=None):
data = form_data if form_data is not None else default_form_data()
browser.find_element(BY_CSS_SELECTOR, FIRST_NAME_SELECTOR).send_keys(data.first_name)
browser.find_element(BY_CSS_SELECTOR, LAST_NAME_SELECTOR).send_keys(data.last_name)
browser.find_element(BY_CSS_SELECTOR, EMAIL_SELECTOR).send_keys(data.email)
if before_submit is not None:
before_submit()
browser.find_element(BY_CSS_SELECTOR, SIGN_UP_BUTTON_SELECTOR).click()
```
## What the browser shows
The form after typing, before the click:
![The sign-up form filled with Jane, Doe and an email address](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/048-fill-out-form/raw/branch/main/docs/images/step-3-form-filled.png)
The page after Sign Up. The demo page checks the email address, and the default `jane.doe@example.com` is rejected. Run the program with your own address (`--email you@yourdomain.com`) to see the success page:
![The demo page answering "Uh oh" to the default example.com address](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/048-fill-out-form/raw/branch/main/docs/images/step-3-form-signed-up.png)
## What we gained
- A CSS selector such as `input[name='fName']` finds an element that has no id.
- Steps 1 and 2 combine here: find, type, click.
- A real page can answer unexpectedly; the screenshot after the click shows what really happened.
- Keeping selectors in `constants.py` means a changed page needs one edit, not a search through the code.
+5
View File
@@ -0,0 +1,5 @@
**Languages**
- English: [Home](Home) · [Step 1](Step-1-Link-Click) · [Step 2](Step-2-Search) · [Step 3](Step-3-Form)
- Dansk: [Forside](Home-da) · [Trin 1](Step-1-Link-Click-da) · [Trin 2](Step-2-Search-da) · [Trin 3](Step-3-Form-da)
- Bahasa Malaysia: [Utama](Home-ms) · [Langkah 1](Step-1-Link-Click-ms) · [Langkah 2](Step-2-Search-ms) · [Langkah 3](Step-3-Form-ms)