@@ -87,27 +87,76 @@ def test_ia_agentique_has_one_five_euro_agent_and_free_coaching(
8787 assert "✨" not in html
8888
8989
90+ def _visible_text (fragment ):
91+ return " " .join (re .sub (r"<[^>]+>" , " " , fragment ).split ())
92+
93+
94+ def _anchor_attributes (container , visible_label ):
95+ matches = []
96+ for anchor in re .finditer (r"<a\s+([^>]*)>(.*?)</a>" , container , re .DOTALL ):
97+ if _visible_text (anchor .group (2 )) == visible_label :
98+ matches .append (anchor .group (1 ))
99+ assert len (matches ) == 1 , f"Expected one anchor labelled { visible_label !r} "
100+ return matches [0 ]
101+
102+
103+ def _article_with_heading (container , heading ):
104+ matches = []
105+ for article in re .findall (r"<article\b[^>]*>(.*?)</article>" , container , re .DOTALL ):
106+ title = re .search (r"<h3\b[^>]*>(.*?)</h3>" , article , re .DOTALL )
107+ if title is not None and _visible_text (title .group (1 )) == heading :
108+ matches .append (article )
109+ assert len (matches ) == 1 , f"Expected one article headed { heading !r} "
110+ return matches [0 ]
111+
112+
90113@pytest .mark .parametrize (
91- ("relative_path" , "offer_path" , "hero_label" , "card_title" , "free_coaching" ),
114+ (
115+ "relative_path" ,
116+ "offer_path" ,
117+ "hero_label" ,
118+ "secondary_label" ,
119+ "card_title" ,
120+ "card_cta" ,
121+ "coaching_label" ,
122+ "coaching_path" ,
123+ "price" ,
124+ ),
92125 [
93126 (
94127 "index.html" ,
95128 "/ia-agentique/" ,
96129 "Agent Web UI + Telegram · 5€" ,
130+ "Voir les réalisations" ,
97131 "Agent Web UI + Telegram" ,
98- "coaching initial gratuit" ,
132+ "Découvrir l'offre →" ,
133+ "Réserver le coaching gratuit" ,
134+ "/ia-agentique/#contact" ,
135+ "5€" ,
99136 ),
100137 (
101138 "en/index.html" ,
102139 "/ia-agentique/en/" ,
103140 "Web UI + Telegram Agent · €5" ,
141+ "See our work" ,
104142 "Web UI + Telegram Agent" ,
105- "free initial coaching" ,
143+ "Discover the offer →" ,
144+ "Book free coaching" ,
145+ "/ia-agentique/en/#contact" ,
146+ "€5" ,
106147 ),
107148 ],
108149)
109150def test_homepage_promotes_the_current_agent_offer (
110- relative_path , offer_path , hero_label , card_title , free_coaching
151+ relative_path ,
152+ offer_path ,
153+ hero_label ,
154+ secondary_label ,
155+ card_title ,
156+ card_cta ,
157+ coaching_label ,
158+ coaching_path ,
159+ price ,
111160):
112161 html = (ROOT / relative_path ).read_text (encoding = "utf-8" )
113162 hero_match = re .search (r'<!-- Hero -->(.*?)<!-- Products -->' , html , re .DOTALL )
@@ -117,20 +166,29 @@ def test_homepage_promotes_the_current_agent_offer(
117166 hero = hero_match .group (1 )
118167 offers = offers_match .group (1 )
119168
120- assert f'href="{ offer_path } "' in hero
121- assert hero_label in hero
122- assert card_title in offers
123- assert f'href="{ offer_path } "' in offers
124- assert free_coaching in offers .lower ()
125- assert "Telegram" in offers
126- assert "5€" in offers or "€5" in offers
127-
128- for obsolete in (
129- "À partir de 10€" ,
130- "Starting from €10" ,
131- "Telegram, Discord, CLI" ,
132- ):
133- assert obsolete not in offers
169+ primary = _anchor_attributes (hero , hero_label )
170+ assert f'href="{ offer_path } "' in primary
171+ assert "bg-primary" in primary
172+
173+ secondary = _anchor_attributes (hero , secondary_label )
174+ assert 'href="#work"' in secondary
175+ assert "border-2" in secondary
176+ assert "bg-primary" not in secondary
177+
178+ agent_card = _article_with_heading (offers , card_title )
179+ card_text = _visible_text (agent_card )
180+ assert price in card_text
181+ assert "Telegram" in card_text
182+ assert "coaching initial gratuit" in card_text .lower () or "free initial coaching" in card_text .lower ()
183+
184+ offer_link = _anchor_attributes (agent_card , card_cta )
185+ assert f'href="{ offer_path } "' in offer_link
186+ coaching_link = _anchor_attributes (agent_card , coaching_label )
187+ assert f'href="{ coaching_path } "' in coaching_link
188+
189+ assert re .search (r"\bDiscord\b" , card_text , re .IGNORECASE ) is None
190+ assert re .search (r"\bCLI\b" , card_text , re .IGNORECASE ) is None
191+ assert re .search (r"(?:10\s*€|€\s*10)" , card_text ) is None
134192
135193
136194@pytest .mark .parametrize (
0 commit comments