Chrome-extensies: eyeo's reis naar het testen van de schorsing van servicemedewerkers

Waar gaat dit over?

De overgang van Manifest V2 naar Manifest V3 brengt een fundamentele verandering met zich mee. In Manifest V2 bevonden extensies zich op een achtergrondpagina. Achtergrondpagina's beheerden de communicatie tussen extensies en webpagina's. Manifest V3 maakt in plaats daarvan gebruik van servicemedewerkers.

In dit bericht gaan we dieper in op het probleem van het testen van medewerkers van de uitbreidingsservice. We kijken vooral hoe we ervoor kunnen zorgen dat ons product correct werkt als een servicemedewerker wordt geschorst.

Wie zijn we?

eyeo is een bedrijf dat zich toelegt op het mogelijk maken van een evenwichtige en duurzame online waarde-uitwisseling voor gebruikers, browsers, adverteerders en uitgevers. We hebben wereldwijd ruim 300 miljoen advertentiefiltergebruikers die de weergave van Acceptabele Advertenties toestaan, een onafhankelijk afgeleide advertentiestandaard die bepaalt of een advertentie acceptabel en niet-opdringerig is.

Ons Extension Engine-team biedt technologie voor advertentiefiltering die enkele van de meest populaire browserextensies voor advertentieblokkering op de markt mogelijk maakt, zoals AdBlock en Adblock Plus met meer dan 110 miljoen gebruikers wereldwijd. Bovendien bieden we deze technologie aan als een open-sourcebibliotheek , waardoor deze beschikbaar wordt voor andere browserextensies voor advertentiefiltering.

Wat is een servicemedewerker?

Extensieservicemedewerkers zijn de centrale gebeurtenishandler van een browserextensie. Ze draaien onafhankelijk op de achtergrond. In grote lijnen is dit prima. De meeste dingen die we moeten doen, kunnen we doen op een achtergrondpagina in de nieuwe servicemedewerker. Maar er zijn een paar veranderingen ten opzichte van achtergrondpagina's:

  • Servicemedewerkers beëindigen hun dienst wanneer ze niet in gebruik zijn . Dit vereist dat we applicatiestatussen volhouden in plaats van te vertrouwen op globale variabelen. Dit betekent dat alle toegangspunten tot ons systeem voorbereid moeten zijn om te worden aangeroepen voordat het systeem wordt geïnitialiseerd.
  • Gebeurtenislisteners moeten worden gekoppeld voordat er op asynchrone callbacks wordt gewacht . Geschorste servicemedewerkers kunnen nog steeds gebeurtenissen ontvangen waarop zij zich hebben geabonneerd. Als de luisteraar voor de gebeurtenis niet is geregistreerd in de eerste beurt van de gebeurtenislus, ontvangt deze de gebeurtenis niet als die gebeurtenis de servicemedewerker heeft wakker gemaakt.
  • Bij inactieve beëindiging kunnen timers worden onderbroken voordat ze zijn voltooid.

Wanneer worden servicemedewerkers geschorst?

Wat we voor Chrome 119 hebben ervaren, is dat servicemedewerkers zijn geschorst:

  • Nadat u gedurende 30 seconden geen gebeurtenissen heeft ontvangen of extensie-API's heeft aangeroepen.
  • Nooit als de ontwikkelaarstools open zijn of als u een op ChromeDriver gebaseerde testbibliotheek gebruikt ( zie functieverzoek ).
  • Als u op Stoppen klikt in chrome://serviceworker-internals.

Voor meer recente informatie raadpleegt u Service Workers Lifecycle .

Waarom is het testen hiervan een probleem?

Idealiter zou het nuttig zijn geweest om officiële richtlijnen te hebben over “hoe je servicemedewerkers op een efficiënte manier kunt testen” of voorbeelden van werkende tests. Tijdens onze avonturen bij het testen van servicemedewerkers kwamen we een aantal uitdagingen tegen:

  • We hebben status in onze testextensie. Wanneer de servicemedewerker stopt, verliezen we de status en de geregistreerde gebeurtenissen. Hoe kunnen we gegevens bewaren in onze teststroom?
  • Als servicemedewerkers op enig moment kunnen worden geschorst, moeten we testen of alle functies werken als ze worden onderbroken.
  • Zelfs als we in onze tests een mechanisme zouden introduceren dat servicemedewerkers willekeurig opschort, is er geen API in de browser om dit gemakkelijk op te schorten. We hebben het W3C-team gevraagd deze functie toe te voegen, maar dat is een voortdurend gesprek.

Testen van schorsing van servicemedewerker

We hebben verschillende manieren geprobeerd om de schorsing van servicemedewerkers tijdens tests te activeren:

Benadering Problemen met de aanpak
Wacht een willekeurige tijd (bijvoorbeeld 30 seconden) Dit maakt het testen traag en onbetrouwbaar, vooral als er meerdere tests worden uitgevoerd. Het werkt niet bij gebruik van WebDriver, omdat WebDriver de DevTools API van Chrome gebruikt en de servicemedewerker niet wordt opgeschort wanneer DevTools geopend is. Zelfs als we dit zouden kunnen omzeilen, zouden we nog steeds moeten controleren of de servicemedewerker geschorst is en we hebben geen manier om dat te doen.
Voer een oneindige lus uit in de servicemedewerker Volgens de specificaties kan dit tot beëindiging leiden, afhankelijk van hoe de browser deze functionaliteit implementeert. Chrome beëindigt de servicemedewerker in dit geval niet, dus we kunnen het scenario niet testen wanneer de servicemedewerker wordt geschorst.
Er is een bericht in de servicemedewerker om te controleren of deze is opgeschort Als u een bericht verzendt, wordt de servicemedewerker wakker. Dit kan worden gebruikt om te controleren of de servicemedewerker sliep, maar het verbreekt de resultaten van tests waarbij controles moeten worden uitgevoerd onmiddellijk nadat de servicemedewerker is geschorst.
Beëindig het servicewerkproces met chrome.processes.terminate() De servicemedewerker voor de extensie deelt een proces met andere delen van de extensie, dus als u dit proces beëindigt met behulp van chrome.process.terminate() of de procesmanager-GUI van Chrome, wordt niet alleen de servicemedewerker gedood, maar ook alle extensiepagina's.

We eindigden met een test die controleert hoe onze code reageert op de schorsing van de servicemedewerker door Selenium WebDriver chrome://serviceworker-internals/ te laten openen en op de knop "stoppen" voor de servicemedewerker te klikken.

Dit is tot nu toe de beste optie, maar het is niet ideaal omdat onze Mocha-tests (die op een extensiepagina worden uitgevoerd) dit niet zelf kunnen doen, dus moeten ze terug communiceren met ons WebDriver-knooppuntprogramma. Dit betekent dat deze tests niet alleen met de extensie kunnen worden uitgevoerd; ze moeten worden geactiveerd met Selenium WebDriver .

Hier is een diagram van hoe we communiceren met de browser-API via verschillende stromen en hoe het toevoegen van het mechanisme voor het opschorten van servicemedewerkers hierop van invloed is.

Diagram dat de teststroom toont
Stroom testen met opschorting van servicemedewerkers.

In een nieuwe stroom die servicemedewerkers opschort (blauw), hebben we Selenium WebDriver toegevoegd om via de gebruikersinterface te klikken op opschorten, wat een actie in de browser-API activeert.

Het is de moeite waard te vermelden dat er een Chrome-bug was waarbij dit met Selenium WebDriver ervoor zorgde dat de servicemedewerker niet opnieuw kon beginnen. Dit is opgelost in Chrome 116 en gelukkig is er ook een oplossing: als je Chrome zo instelt dat DevTools op elk tabblad automatisch wordt geopend, start de servicemedewerker correct op.

Dit is de aanpak die we gebruiken bij het testen, ook al is het niet ideaal, omdat het klikken op de knop mogelijk geen stabiele API is en het openen van DevTools (voor oudere browsers) prestatiekosten met zich mee lijkt te brengen.

Hoe dekken we de volledige functionaliteit? Fuzz-testen

Toen we eenmaal een mechanisme hadden om de opschorting te testen, moesten we beslissen hoe we dit in onze automatiseringstestsuites zouden aansluiten. We hebben onze standaardtests uitgevoerd in een omgeving waarin vóór elke interactie met de achtergrondpagina de servicemedewerker wordt opgeschort doordat WebDriver op Stop klikt op de chrome://serviceworker-internals/ pagina.

Een voorbeeld van een fuzz-testuitvoering
Afbeelding met de huidige opzet van tests.

We voeren de meeste en niet alle tests uit omdat het ophangmechanisme niet volledig stabiel is en soms schilfers veroorzaakt. Bovendien kost het veel tijd om alle testsuites in de fuzz-modus uit te voeren. Dus in plaats van alle "soortgelijke" gevallen te behandelen, hebben we de meest kritieke paden gekozen voor testen in de fuzz-modus. Het is de moeite waard te vermelden dat het uitvoeren van functionele tests in de "fuzz"-modus betekent dat we de time-outs van de tests moesten verlengen, omdat het opschorten en opnieuw opstarten van servicemedewerkers extra tijd kost.

Deze tests zijn waardevol als een grofkorrelige eerste doorgang, die veel plaatsen belicht waar de code faalt, maar niet noodzakelijkerwijs alle subtiele manieren blootlegt waarop de schorsing van servicemedewerkers ervoor kan zorgen dat dingen kapot gaan.

Intern noemen we dit soort tests ‘Fuzz-tests’. Traditioneel is fuzz-testen het uitvoeren van ongeldige invoer naar uw programma en ervoor zorgen dat het redelijk reageert, of in ieder geval niet crasht. In ons geval is de 'ongeldige invoer' dat de servicemedewerker op elk moment wordt geschorst, en het 'redelijke gedrag' dat we verwachten is dat onze advertentiefilterfunctionaliteit moet blijven werken zoals voorheen. Dit is niet echt ongeldige invoer, aangezien dit het verwachte gedrag is in Manifest V3, maar dit zou ongeldig zijn geweest in Manifest V2, dus het voelt als redelijke terminologie.

Samenvatting

Servicemedewerkers zijn een van de grootste veranderingen in Manifest V3 (naast declarativeNetRequest-regels). Migratie naar Manifest V3 kan veel codewijzigingen in browserextensies en nieuwe testbenaderingen vereisen. Het vereist ook dat ontwikkelaars van extensies met een persistente status hun extensies voorbereiden op het op een elegante manier omgaan met onverwachte opschorting van servicemedewerkers.

Helaas is er geen API om opschorting op een eenvoudige manier af te handelen die past bij onze gebruikssituatie. Omdat we in een vroege fase de robuustheid van de codebasis van onze extensie wilden testen op basis van opschortingsmechanismen, moesten we er omheen werken. Andere ontwikkelaars van extensies die met soortgelijke uitdagingen worden geconfronteerd, kunnen deze oplossing gebruiken. Hoewel deze oplossing tijdrovend is in de ontwikkelings- en onderhoudsfase, is deze de moeite waard, zodat we ervoor kunnen zorgen dat onze extensies met succes kunnen functioneren in een omgeving waarin servicemedewerkers regelmatig worden geschorst.

Ook al is er al basisondersteuning voor het testen van de opschorting van servicemedewerkers , een betere platformondersteuning voor het testen van servicemedewerkers vanuit extensies is iets dat we in de toekomst heel graag zouden zien, omdat dit onze testuitvoeringstijden en onderhoudsinspanningen aanzienlijk zou kunnen verkorten.