Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd73485e35 | ||
|
|
0e1208726f |
@@ -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 |
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
# 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 | [0e12087] |
|
||||
|
||||
---
|
||||
|
||||
## 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
|
||||
[0e12087]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/052-instagram-followers/commit/0e1208726f3ae1b083b198598311137e2fc99f58
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
|
||||

|
||||
|
||||
## 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`.
|
||||
@@ -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`.
|
||||
|
||||

|
||||
|
||||
## 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`.
|
||||
@@ -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.
|
||||
|
||||

|
||||
|
||||
## 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`.
|
||||
@@ -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.
|
||||
|
||||

|
||||
|
||||
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:`).
|
||||
@@ -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.
|
||||
|
||||

|
||||
|
||||
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:`).
|
||||
@@ -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.
|
||||
|
||||

|
||||
|
||||
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:`).
|
||||
@@ -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".
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
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.
|
||||
@@ -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".
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
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.
|
||||
@@ -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.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
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.
|
||||
@@ -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.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
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`.
|
||||
|
||||

|
||||
|
||||
## 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.
|
||||
@@ -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.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
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`.
|
||||
|
||||

|
||||
|
||||
## 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.
|
||||
@@ -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.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
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`.
|
||||
|
||||

|
||||
|
||||
## 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.
|
||||
@@ -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.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## 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.
|
||||
@@ -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.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## 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.
|
||||
@@ -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.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## 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.
|
||||
@@ -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)
|
||||
Reference in New Issue
Block a user