What Apostate changes
A persona is the platform a launch presents. It sets the operating system in theUser-Agent, the Client Hints and navigator.platform, which ad servers and landing pages use to pick a creative or a download page. Personas are Windows, macOS and Linux desktops. Apostate has no mobile personas.
A proxy gives the visit an IP address in the region. Before launch, the package sets the locale and timezone from the proxy’s exit, so the language and timezone agree with the IP address.
Set up
apostate fonts install windows is for Linux and macOS hosts (Fonts).
verify_ads.py takes an ad or tracking link. For each region, it reads a proxy from APOSTATE_PROXY_US, APOSTATE_PROXY_DE or APOSTATE_PROXY_FR and skips a region whose variable is not set. With no link, it runs against a local ad server. The server redirects /click to /track, and /track to a landing page in the language of Accept-Language. The landing page’s script sends Mac visitors on to a /mac page.
The script
follow() opens the link with one persona and records each response to a main-frame navigation. That covers HTTP redirects and navigations a page’s script starts:
Run the demo
302 lines are the HTTP redirects. The tracker chose the landing page from Accept-Language. Under the macOS persona, the landing page’s script moved on to /mac, which shows as a second 200.
Run through regional proxies
Set a proxy for each region you want to check, then pass the link:apostate: , and the persona uses en-US and the host’s timezone. From 0.4.4 the warning is also in browser.apostate_diagnostics["warnings"]. Proxies covers the lookup.
Points for this job
- Proxies. Use one exit per region, sticky for the length of a launch. Proxies covers sticky sessions.
- Seeds. Each persona uses seed 42, so a rerun visits with the same two machines and a change in the result comes from the campaign. To see how a campaign treats other machines of one persona, add seeds.
- What the chain records. The chain holds HTTP redirects and the navigations a page’s script starts, such as
location.replace(). An ad inside an iframe navigates its own frame, so filter on that frame instead ofpage.main_frame.wait_for_load_state("networkidle")returns after 500 ms with no network connections. The chain misses a redirect that a page schedules later than that. To catch it, addpage.wait_for_timeout()before the screenshot. - Headless. The screenshots are full-page captures from a headless launch, which presents the persona’s screen and window.