MIL-004 Wiki #20

Open
Tirsvad wants to merge 2 commits from mil-004-wiki into mil-003-readme-and-screenshots
21 changed files with 367 additions and 1 deletions
Showing only changes of commit 0e1208726f - Show all commits
+1 -1
View File
@@ -15,7 +15,7 @@ document of a type. `Primary File` may contain a glob (e.g.
| SA | Stakeholder Analysis | docs/stakeholder-analysis.md | 002 |
| PP | Project Plan | docs/project-plan.md | 002 |
| MIL | Milestone / Gateway | docs/milestones/*.md | 005 |
| RC | SQA Review Record | docs/sqa/reviews/rc-*.md | 010 |
| RC | SQA Review Record | docs/sqa/reviews/rc-*.md | 011 |
| DICT | Domain Dictionary | docs/dictionary.md | 002 |
| TM | Traceability Matrix | docs/sqa/traceability-matrix.md | 002 |
+58
View File
@@ -0,0 +1,58 @@
# Review of MIL-004
## Metadata
| Key | Value |
| --- | --- |
| ID | RC-010 |
| CrossReference | [MIL-004], [QC-WIKI-001] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-11-04 | Proposed | Jens Tirsvad Nielsen | S01 (AI as stand-in) | Initial version | pending |
---
## Artifact Under Review
- Instance reviewed: [MIL-004]
- Checklist used: [QC-WIKI-001]
- Scope: full review of docs/wiki on branch mil-004-wiki
- Language and domain: n/a
- Language reviewer: none (the stand-in for S01 reads English and the IT domain)
- Mode: autonomous, not independent (reviewer is AI as stand-in for S01)
## Checklist Results
| # | Criterion | Status | Evidence/Notes |
| --- | --- | --- | --- |
| 1 | The wiki has a `_Sidebar.md`, because the host lists subpages only through it | Pass | exists. |
| 2 | The sidebar starts with the wiki's title in bold, then one list of the pages in the primary language (English), `Home` first | Pass | Bold title, one English page list, Home first. |
| 3 | The page list holds a link to every English page of the wiki, and no link points to a page that does not exist | Pass | All six English pages are listed; a script checked that no link in the wiki points to a missing page. |
| 4 | A `**Related**` section follows the page list only when the wiki has related wikis (for example the checklists wiki for a framework wiki); each entry is a link to that wiki's Home. A wiki with nothing related has no such section | N-A | The wiki has no related wikis, so no Related section exists, as the criterion requires. |
| 5 | A `**Languages**` section is the last section of the sidebar. It has one line per language, the language written in that language, linking to that language's `Home` page | Pass | Languages section is last, one line per language in that language. |
| 6 | The sidebar does not repeat the page list per language | Pass | The page list appears once. |
| 7 | A sidebar produced by a generator carries a comment that says so and names the generator; the generator is changed, not the page | N-A | The sidebar is written by hand, not by a generator. |
| 8 | The wiki has a `Languages` line on each page (criterion 11), so the sidebar is not the only way to switch language | Pass | Every page has the language line. |
| 9 | Every wiki exists in English and, as a minimum, in the language the project's registry names as the PO language; further languages are added on top, never instead of English | Pass | English plus Danish and Bahasa Malaysia, as the Product Owner asked (the PO language is English). |
| 10 | Every English page has a page in each other language of the wiki: the page sets are identical | Pass | 6 pages in each of en, da and ms (18 pages). |
| 11 | Every page starts with the language line, with the current language in bold and a link to the same page in each other language | Pass | Each page starts with the line, the current language in bold. |
| 12 | A page in a language other than English is named `<Page>-<code>.md`, with a BCP 47 code; English has no suffix | Pass | Suffixes -da and -ms, English has none. |
| 13 | Code blocks, commands, file names and IDs stay in English in every language | Pass | Code, commands, file names and IDs are English in all languages. |
| 14 | The sidebar, every page and every link were checked on the published wiki after the change, not only in the repository | Pending | The wiki is published only after the pull request merges into main, so it cannot be checked on the host yet. The images also resolve only after the merge. |
| 15 | A change to the layout rules (sections, order, naming) is made in the generator or template and in this checklist's source rules together | N-A | No change to layout rules. |
## Overall Verdict
Go-with-conditions — All checkable Mandatory criteria pass. Criterion 14 is Pending until the wiki is published, so Go-with-conditions is the highest verdict.
## Action Items
| Action | Owner | Due |
| --- | --- | --- |
| After the merge, open the published wiki and check the sidebar, every page, every link and every image on the host | S01 | 2026-11-04 |
---
[MIL-004]: ../../milestones/mil-004-wiki.md
[QC-WIKI-001]: ../../../framework/qc/artifacts/qc-wiki.md
+15
View File
@@ -0,0 +1,15 @@
[English](Home) · **Dansk** · [Bahasa Malaysia](Home-ms)
# Instagram Followers
En Selenium-bot fra dag 52 i Udemy-kurset "100 Days of Code: The Complete Python Pro Bootcamp". Den logger ind på mock-tjenesten Share-a-Naan, åbner en målkonto og følger hver af dens følgere.
Wikien følger forelæsningens fem trin. Hver side har skærmbillederne fra trinnet og det, vi lærte af det.
- [Trin 1 - Loginoplysninger](Step-1-Credentials-da)
- [Trin 2 - Klasse](Step-2-Class-da)
- [Trin 3 - Login](Step-3-Login-da)
- [Trin 4 - Find følgerne](Step-4-Find-Followers-da)
- [Trin 5 - Følg](Step-5-Follow-da)
Kør den kun mod mock-tjenesten. Den rigtige Instagram kan udelukke en konto, der opfører sig som en bot. Se repositoriets README for kommandoerne til at installere, køre og teste.
+15
View File
@@ -0,0 +1,15 @@
[English](Home) · [Dansk](Home-da) · **Bahasa Malaysia**
# Instagram Followers
Bot Selenium daripada hari ke-52 kursus Udemy "100 Days of Code: The Complete Python Pro Bootcamp". Ia log masuk ke perkhidmatan tiruan Share-a-Naan, membuka akaun sasaran dan mengikut setiap pengikutnya.
Wiki ini mengikut lima langkah kuliah. Setiap halaman mempunyai tangkapan skrin langkah itu dan apa yang kami peroleh daripadanya.
- [Langkah 1 - Maklumat log masuk](Step-1-Credentials-ms)
- [Langkah 2 - Kelas](Step-2-Class-ms)
- [Langkah 3 - Log masuk](Step-3-Login-ms)
- [Langkah 4 - Cari pengikut](Step-4-Find-Followers-ms)
- [Langkah 5 - Ikut](Step-5-Follow-ms)
Jalankan hanya pada perkhidmatan tiruan. Instagram sebenar boleh menyekat akaun yang bertindak seperti bot. Lihat README repositori untuk arahan memasang, menjalankan dan menguji.
+15
View File
@@ -0,0 +1,15 @@
**English** · [Dansk](Home-da) · [Bahasa Malaysia](Home-ms)
# Instagram Followers
A Selenium bot from Day 52 of the Udemy course "100 Days of Code: The Complete Python Pro Bootcamp". It logs in to the Share-a-Naan mock service, opens a target account and follows each of its followers.
The wiki follows the five steps of the lecture. Each page has the screenshots of the step and what we gained from it.
- [Step 1 - Credentials](Step-1-Credentials)
- [Step 2 - Class](Step-2-Class)
- [Step 3 - Login](Step-3-Login)
- [Step 4 - Find the followers](Step-4-Find-Followers)
- [Step 5 - Follow](Step-5-Follow)
Run it only against the mock service. The real Instagram can ban an account that behaves like a bot. See the README of the repository for the commands to install, run and test.
+13
View File
@@ -0,0 +1,13 @@
[English](Step-1-Credentials) · **Dansk** · [Bahasa Malaysia](Step-1-Credentials-ms)
# Trin 1 - Loginoplysninger
Opgaven starter med en konto. Vi bruger mock-tjenesten Share-a-Naan i stedet for den rigtige Instagram, så en ændret side eller en udelukkelse ikke kan gøre skade. Mock-tjenestens profilside viser login (e-mailen er brugernavnet) og de målkonti, man kan vælge `SIMILAR_ACCOUNT` blandt.
![Target accounts on the profile page](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step1-target-accounts.jpg)
## Hvad vi lærte
- Et sikkert sted at øve: en mock-tjeneste lader os få logikken rigtig, før en rigtig konto er i fare.
- Hemmeligheder holdes ude af koden: adgangskoden læses fra miljøvariablerne `INSTA_USERNAME` og `INSTA_PASSWORD`, og `.env` står i `.gitignore`.
- Konstanter ligger i én fil, `constants.py`: `SIMILAR_ACCOUNT`, `BASE_URL` og `LOGIN_URL`.
+13
View File
@@ -0,0 +1,13 @@
[English](Step-1-Credentials) · [Dansk](Step-1-Credentials-da) · **Bahasa Malaysia**
# Langkah 1 - Maklumat log masuk
Tugasan bermula dengan sebuah akaun. Kami menggunakan perkhidmatan tiruan Share-a-Naan dan bukannya Instagram sebenar, supaya halaman yang berubah atau sekatan tidak menjejaskan sesiapa. Halaman profil perkhidmatan tiruan itu menunjukkan log masuk (e-mel ialah nama pengguna) dan akaun sasaran untuk memilih `SIMILAR_ACCOUNT`.
![Target accounts on the profile page](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step1-target-accounts.jpg)
## Apa yang kami peroleh
- Tempat selamat untuk berlatih: perkhidmatan tiruan membolehkan kami membetulkan logik sebelum akaun sebenar berisiko.
- Rahsia dijauhkan daripada kod: kata laluan dibaca daripada pemboleh ubah persekitaran `INSTA_USERNAME` dan `INSTA_PASSWORD`, dan `.env` ada dalam `.gitignore`.
- Pemalar disimpan dalam satu fail, `constants.py`: `SIMILAR_ACCOUNT`, `BASE_URL` dan `LOGIN_URL`.
+13
View File
@@ -0,0 +1,13 @@
**English** · [Dansk](Step-1-Credentials-da) · [Bahasa Malaysia](Step-1-Credentials-ms)
# Step 1 - Credentials
The assignment starts with an account. We use the Share-a-Naan mock instead of the real Instagram, so a changed page or a ban cannot hurt. The profile page of the mock shows the login (the email is the username) and the target accounts to choose `SIMILAR_ACCOUNT` from.
![Target accounts on the profile page](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step1-target-accounts.jpg)
## What we gained
- A safe place to practise: a mock service lets us get the logic right before any real account is at risk.
- Secrets stay out of the code: the password is read from the environment variables `INSTA_USERNAME` and `INSTA_PASSWORD`, and `.env` is in `.gitignore`.
- Constants live in one file, `constants.py`: `SIMILAR_ACCOUNT`, `BASE_URL` and `LOGIN_URL`.
+15
View File
@@ -0,0 +1,15 @@
[English](Step-2-Class) · **Dansk** · [Bahasa Malaysia](Step-2-Class-ms)
# Trin 2 - Klasse
Fordi botten har flere trin, er koden organiseret i en klasse, `InstaFollower`. `__init__` opretter Selenium-driveren. De tre metoder `login()`, `find_followers()` og `follow()` kaldes i den rækkefølge.
![Outline of the InstaFollower class](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step2-class-outline.png)
Klassen er Selenium-adapteren i laget `infrastructure`. Et lille use case, `run_bot`, kalder de tre metoder gennem en `Follower`-protokol, så rækkefølgen testes uden en browser.
## Hvad vi lærte
- At samle trin, der deler tilstand (driveren), i en klasse.
- At injicere driveren og sleep-funktionen, så tests bruger en falsk driver og aldrig venter.
- At lukke browseren med en context manager (`with InstaFollower() as follower:`).
+15
View File
@@ -0,0 +1,15 @@
[English](Step-2-Class) · [Dansk](Step-2-Class-da) · **Bahasa Malaysia**
# Langkah 2 - Kelas
Oleh sebab bot mempunyai beberapa langkah, kod disusun dalam sebuah kelas, `InstaFollower`. `__init__` mencipta pemacu Selenium. Tiga kaedah `login()`, `find_followers()` dan `follow()` dipanggil mengikut urutan itu.
![Outline of the InstaFollower class](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step2-class-outline.png)
Kelas ini ialah penyesuai Selenium dalam lapisan `infrastructure`. Satu kes guna kecil, `run_bot`, memanggil tiga kaedah melalui protokol `Follower`, jadi urutan diuji tanpa pelayar.
## Apa yang kami peroleh
- Mengumpulkan langkah yang berkongsi keadaan (pemacu) dalam satu kelas.
- Menyuntik pemacu dan fungsi tidur supaya ujian menggunakan pemacu palsu dan tidak menunggu.
- Menutup pelayar dengan context manager (`with InstaFollower() as follower:`).
+15
View File
@@ -0,0 +1,15 @@
**English** · [Dansk](Step-2-Class-da) · [Bahasa Malaysia](Step-2-Class-ms)
# Step 2 - Class
Because the bot has several steps, the code is organised in a class, `InstaFollower`. `__init__` creates the Selenium driver. The three methods `login()`, `find_followers()` and `follow()` are called in that order.
![Outline of the InstaFollower class](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step2-class-outline.png)
The class is the Selenium adapter in the `infrastructure` layer. A small use case, `run_bot`, calls the three methods through a `Follower` protocol, so the order is tested without a browser.
## What we gained
- Grouping steps that share state (the driver) in a class.
- Injecting the driver and the sleep function, so tests use a fake driver and never wait.
- Closing the browser with a context manager (`with InstaFollower() as follower:`).
+19
View File
@@ -0,0 +1,19 @@
[English](Step-3-Login) · **Dansk** · [Bahasa Malaysia](Step-3-Login-ms)
# Trin 3 - Login
`login()` åbner loginsiden, udfylder e-mail og adgangskode og trykker på "Log in". Så følger to pop-ups: "Save your login info?" og "Turn on notifications". Begge lukkes med knappen "Not Now".
![Share-a-Naan login page](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step3-login-page.jpg)
![Save your login info pop-up](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step3-save-info-popup.jpg)
![Turn on notifications pop-up](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step3-notifications-popup.jpg)
På den rigtige Instagram ændrer XPaths og selektorer sig ved hvert besøg. Løsningen er at finde en knap på dens tekst, for eksempel `//button[contains(text(), 'Not Now')]`, og ikke på et genereret klassenavn.
## Hvad vi lærte
- At finde elementer på synlig tekst med `contains()` og `text()`, som overlever ændringer i layoutet.
- At vente på et element med `WebDriverWait` i stedet for en fast pause.
- At håndtere valgfrie pop-ups: klik på dem, hvis de findes, og fortsæt, hvis de ikke gør.
+19
View File
@@ -0,0 +1,19 @@
[English](Step-3-Login) · [Dansk](Step-3-Login-da) · **Bahasa Malaysia**
# Langkah 3 - Log masuk
`login()` membuka halaman log masuk, mengisi e-mel dan kata laluan, kemudian menekan "Log in". Dua tetingkap timbul menyusul: "Save your login info?" dan "Turn on notifications". Kedua-duanya ditutup dengan butang "Not Now".
![Share-a-Naan login page](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step3-login-page.jpg)
![Save your login info pop-up](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step3-save-info-popup.jpg)
![Turn on notifications pop-up](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step3-notifications-popup.jpg)
Pada Instagram sebenar, XPath dan pemilih berubah pada setiap lawatan. Penyelesaiannya ialah mencari butang melalui perkataannya, contohnya `//button[contains(text(), 'Not Now')]`, dan bukan melalui nama kelas yang dijana.
## Apa yang kami peroleh
- Mencari elemen melalui teks yang kelihatan dengan `contains()` dan `text()`, yang tahan perubahan reka letak.
- Menunggu elemen dengan `WebDriverWait` dan bukan jeda tetap.
- Mengendalikan tetingkap timbul pilihan: klik jika ada dan teruskan jika tiada.
+19
View File
@@ -0,0 +1,19 @@
**English** · [Dansk](Step-3-Login-da) · [Bahasa Malaysia](Step-3-Login-ms)
# Step 3 - Login
`login()` opens the login page, fills in the email and password and presses "Log in". Two pop-ups follow: "Save your login info?" and "Turn on notifications". Both are closed with the "Not Now" button.
![Share-a-Naan login page](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step3-login-page.jpg)
![Save your login info pop-up](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step3-save-info-popup.jpg)
![Turn on notifications pop-up](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step3-notifications-popup.jpg)
On the real Instagram the XPaths and selectors change on every visit. The fix is to find a button by its words, for example `//button[contains(text(), 'Not Now')]`, and not by a generated class name.
## What we gained
- Locating elements by visible text with `contains()` and `text()`, which survives layout changes.
- Waiting for an element with `WebDriverWait` instead of a fixed pause.
- Handling optional pop-ups: click them if present and carry on if not.
+19
View File
@@ -0,0 +1,19 @@
[English](Step-4-Find-Followers) · **Dansk** · [Bahasa Malaysia](Step-4-Find-Followers-ms)
# Trin 4 - Find følgerne
`find_followers()` åbner målkontoens side på `/u/<konto>` og klikker på linket til følgerne. Listen i modalen indlæser først omkring et dusin følgere, så vi ruller for at indlæse resten.
![Profile of the target account](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step4-target-profile.jpg)
![Followers modal](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step4-followers-modal.jpg)
Modalen er ikke det element, der ruller. Den rullende del er det indre `followers-scroll`-element, så scriptet ruller det element: `arguments[0].scrollTop = arguments[0].scrollHeight`.
![Followers modal scrolled to the end](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step4-followers-scrolled.jpg)
## Hvad vi lærte
- At køre JavaScript fra Selenium med `execute_script`.
- At finde det element, der virkelig ruller, ved at undersøge siden i stedet for at rulle hele vinduet.
- At holde pause mellem rulninger, så siden kan indlæse flere poster.
+19
View File
@@ -0,0 +1,19 @@
[English](Step-4-Find-Followers) · [Dansk](Step-4-Find-Followers-da) · **Bahasa Malaysia**
# Langkah 4 - Cari pengikut
`find_followers()` membuka halaman akaun sasaran di `/u/<akaun>` dan mengklik pautan pengikut. Senarai dalam modal pada mulanya memuatkan kira-kira sedozen pengikut, maka kami menatal untuk memuatkan selebihnya.
![Profile of the target account](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step4-target-profile.jpg)
![Followers modal](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step4-followers-modal.jpg)
Modal bukan elemen yang menatal. Bahagian yang boleh ditatal ialah elemen dalaman `followers-scroll`, jadi skrip menatal elemen itu: `arguments[0].scrollTop = arguments[0].scrollHeight`.
![Followers modal scrolled to the end](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step4-followers-scrolled.jpg)
## Apa yang kami peroleh
- Menjalankan JavaScript daripada Selenium dengan `execute_script`.
- Mencari elemen yang benar-benar menatal dengan memeriksa halaman, bukan menatal seluruh tetingkap.
- Berhenti seketika antara tatalan supaya halaman sempat memuatkan lebih banyak entri.
+19
View File
@@ -0,0 +1,19 @@
**English** · [Dansk](Step-4-Find-Followers-da) · [Bahasa Malaysia](Step-4-Find-Followers-ms)
# Step 4 - Find the followers
`find_followers()` opens the page of the target account at `/u/<account>` and clicks the followers link. The list in the modal loads about a dozen followers at first, so we scroll to load the rest.
![Profile of the target account](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step4-target-profile.jpg)
![Followers modal](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step4-followers-modal.jpg)
The modal is not the scrolling element. The scrollable part is the inner `followers-scroll` element, so the script scrolls that element: `arguments[0].scrollTop = arguments[0].scrollHeight`.
![Followers modal scrolled to the end](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step4-followers-scrolled.jpg)
## What we gained
- Running JavaScript from Selenium with `execute_script`.
- Finding the element that really scrolls by inspecting the page, instead of scrolling the whole window.
- Pausing between scrolls so the page can load more entries.
+17
View File
@@ -0,0 +1,17 @@
[English](Step-5-Follow) · **Dansk** · [Bahasa Malaysia](Step-5-Follow-ms)
# Trin 5 - Følg
`follow()` finder hver "Follow"-knap i følgerlisten og klikker på den med et sekunds pause mellem klikkene, så botten ligner en maskine mindre. Knapper, der allerede siger "Following", springes over.
Hvis et klik opfanges af pop-up'en "Unfollow?" (en konto, man allerede følger), rejser Selenium `ElementClickInterceptedException`. Botten klikker på "Cancel" og fortsætter med næste knap.
![Unfollow pop-up with a Cancel button](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step5-unfollow-popup.jpg)
![Followers after the follow loop](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step5-followed.jpg)
## Hvad vi lærte
- At håndtere en bestemt undtagelse med vilje: ingen bar `except`, kun det tilfælde, opgaven beskriver.
- At teste fejlstien med en falsk driver, der rejser undtagelsen.
- At vise respekt for tjenesten: et sekund mellem klik og en mock-tjeneste med en "Reset Share-a-Naan"-knap til rene genkørsler.
+17
View File
@@ -0,0 +1,17 @@
[English](Step-5-Follow) · [Dansk](Step-5-Follow-da) · **Bahasa Malaysia**
# Langkah 5 - Ikut
`follow()` mencari setiap butang "Follow" dalam senarai pengikut dan mengkliknya dengan jeda satu saat antara klik, supaya bot kurang kelihatan seperti mesin. Butang yang sudah menyatakan "Following" dilangkau.
Jika klik dipintas oleh tetingkap timbul "Unfollow?" (akaun yang sudah diikuti), Selenium menimbulkan `ElementClickInterceptedException`. Bot mengklik "Cancel" dan meneruskan dengan butang seterusnya.
![Unfollow pop-up with a Cancel button](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step5-unfollow-popup.jpg)
![Followers after the follow loop](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step5-followed.jpg)
## Apa yang kami peroleh
- Mengendalikan pengecualian tertentu dengan sengaja: tiada `except` kosong, hanya kes yang diterangkan dalam tugasan.
- Menguji laluan ralat itu dengan pemacu palsu yang menimbulkan pengecualian.
- Menghormati perkhidmatan: satu saat antara klik, dan perkhidmatan tiruan dengan butang "Reset Share-a-Naan" untuk larian semula yang bersih.
+17
View File
@@ -0,0 +1,17 @@
**English** · [Dansk](Step-5-Follow-da) · [Bahasa Malaysia](Step-5-Follow-ms)
# Step 5 - Follow
`follow()` finds every "Follow" button in the followers list and clicks it with a one second pause between clicks, so the bot looks less like a machine. Buttons that already say "Following" are skipped.
If a click is intercepted by the "Unfollow?" pop-up (an account that is already followed), Selenium raises `ElementClickInterceptedException`. The bot clicks "Cancel" and carries on with the next button.
![Unfollow pop-up with a Cancel button](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step5-unfollow-popup.jpg)
![Followers after the follow loop](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/raw/branch/main/docs/images/step5-followed.jpg)
## What we gained
- Handling a specific exception on purpose: no bare `except`, and only the case the assignment describes.
- Testing that error path with a fake driver that raises the exception.
- Respecting the service: one second between clicks, and a mock service with a "Reset Share-a-Naan" button for clean re-runs.
+14
View File
@@ -0,0 +1,14 @@
**Instagram Followers**
- [Home](Home)
- [Step 1 - Credentials](Step-1-Credentials)
- [Step 2 - Class](Step-2-Class)
- [Step 3 - Login](Step-3-Login)
- [Step 4 - Find the followers](Step-4-Find-Followers)
- [Step 5 - Follow](Step-5-Follow)
**Languages**
- English: [Home](Home)
- Dansk: [Hjem](Home-da)
- Bahasa Melayu: [Utama](Home-ms)