תוספים ל-Chrome: התהליך לבדיקת השעיה של קובץ שירות (service worker)

על מה מדובר?

המעבר ממניפסט V2 למניפסט V3 כולל שינוי מהותי. במניפסט מגרסה 2, התוספים הוצגו בדף רקע. דפי רקע ניהלו את התקשורת בין תוספים ודפי אינטרנט. במניפסט V3 נעשה שימוש ב-Service Workers במקום זאת.

בפוסט הזה, נפרט את הבעיה של בדיקת קובצי שירות (service worker) של תוספים. באופן ספציפי, אנחנו בודקים איך לוודא שהמוצר שלנו פועל כמו שצריך במקרה של השעיית קובץ שירות (service worker).

מי אנחנו?

eyeo היא חברה המתמקדת ביצירת חילופי ערך מקוונים מאוזנים ובת קיימא עבור משתמשים, דפדפנים, מפרסמים ובעלי תוכן דיגיטלי. יש לנו יותר מ-300 מיליון משתמשים גלובליים שמבצעים סינון מודעות, שמאפשרים לנו להציג את 'מודעות מקובלות', תקן מודעות נגזר באופן בלתי תלוי שקובע אם מודעה מקובלת ולא פולשנית.

צוות Extension Engine שלנו מספק טכנולוגיה לסינון מודעות שמפעילה כמה מתוספי הדפדפן הפופולריים ביותר בשוק לחסימת מודעות, כמו AdBlock ו-Adblock Plus, עם יותר מ-110 מיליון משתמשים ברחבי העולם. בנוסף, אנחנו מציעים את הטכנולוגיה הזו כספריית קוד פתוח, כך שהיא זמינה לתוספים אחרים לדפדפן לסינון מודעות.

מהו קובץ שירות (service worker)?

עובדי שירות של תוספים הם הגורם המטפל באירועים מרכזיים של תוסף לדפדפן. הן פועלות ברקע באופן עצמאי. בגדול, זה בסדר. נוכל לעשות את רוב הפעולות שאנחנו צריכים לבצע בדף רקע ב-Service Worker החדש. עם זאת, יש כמה שינויים בהשוואה לדפי רקע:

  • קובצי שירות (service worker) מסתיימים כשהם לא בשימוש. לשם כך עלינו להמשיך לשמור על מצבי האפליקציה במקום להסתמך על משתנים גלובליים. כלומר, כל נקודות הכניסה למערכת שלנו צריכות להיות מוכנות לקריאה לפני אתחול המערכת.
  • צריך לצרף פונקציות event listener לפני שממתינים לקריאות חוזרות (callback) אסינכרוניות. עובדי שירות מושעים עדיין יכולים לקבל אירועים שהם נרשמו אליהם. אם ה-listener של האירוע לא רשום בהפעלה הראשונה של לולאת האירוע, הוא לא יקבל את האירוע אם האירוע הזה יתעורר את ה-Service Worker.
  • סיום מצב 'לא פעיל' יכול לקטוע את הטיימרים לפני שהם מסיימים.

מתי מושעים קובצי שירות (service worker)?

בגרסה 119 של Chrome, ה-Service Workers הושעו:

  • אחרי שלא התקבלו אירועים או ממשקי API של תוסף הקריאה לפעולה במשך 30 שניות.
  • אף פעם לא אם הכלים למפתחים פתוחים או אם אתם משתמשים בספריית בדיקות שמבוססת על ChromeDriver (אפשר לעיין בבקשה להוספת תכונה).
  • אם לוחצים על עצירה ב-chrome://serviceworker-internals.

מידע עדכני יותר זמין במחזור החיים של Service Workers.

מדוע ביצוע הבדיקה הזו מהווה בעיה?

באופן אידיאלי, היה כדאי לקבל הדרכה רשמית לגבי "איך לבדוק Service Workers בדרך יעילה" או דוגמאות של בדיקות פועלות. במהלך ההרפתקאות שלנו בבדיקת עובדי שירות, התמודדנו עם כמה אתגרים:

  • יש לנו מצב בתוסף הבדיקה שלנו. כשה-Service Worker מפסיק, אנחנו מאבדים את המצב שלו ואת האירועים הרשומים שלו. איך נוכל לשמור על הנתונים בתהליך הבדיקה שלנו?
  • אם אפשר להשעות את ה-Service Workers בכל שלב, עלינו לבדוק שכל התכונות פועלות אם יש שיבושים בהם.
  • גם אם נציג בבדיקות שלנו מנגנון שמשעה באופן אקראי את ה-Service Workers, אין בדפדפן ממשק API שיכול להשעות אותו בקלות. ביקשנו מצוות W3C להוסיף את התכונה הזו, אבל זאת שיחה מתמשכת.

בדיקת השעיה של קובץ שירות (service worker)

ניסינו כמה גישות להפעלת ההשעיה של קובצי שירות (service worker) במהלך בדיקות:

הגישה בעיות בגישה
להמתין משך זמן שרירותי (לדוגמה 30 שניות) לכן הבדיקה איטית ולא אמינה, במיוחד כשמריצים מספר בדיקות. היא לא פועלת כשמשתמשים ב-WebDriver כי WebDriver משתמש ב-DevTools API של Chrome, וה-Service Worker לא מושעה כשכלי הפיתוח פתוחים. גם אם נוכל לעקוף זאת, עדיין נצטרך לבדוק אם ה-Service Worker הושעה ואין לנו דרך לעשות זאת.
מריצים לולאה אינסופית ב-Service Worker לפי המפרט, זה עלול להוביל לסגירה בהתאם לאופן שבו הדפדפן מטמיע את הפונקציונליות הזו. במקרה זה Chrome לא מסיים את קובץ השירות (service worker), כך שאנחנו לא יכולים לבדוק את התרחיש במקרה של השעיית קובץ השירות.
הוספת הודעה בקובץ השירות (service worker) כדי לבדוק אם הוא הושעה שליחת הודעה תעיר את קובץ השירות (service worker). ניתן להשתמש בכך כדי לבדוק אם ה-Service Worker היה במצב שינה, אבל היא גורמת לשיבושים בתוצאות עבור בדיקות שצריך לבצע בדיקות מיד לאחר השעיית ה-Service Worker.
הפסקת התהליך של קובץ השירות (service worker) באמצעות chrome.processinges.terminate() ה-service worker של התוסף משתף תהליך עם חלקים אחרים של התוסף, ולכן סגירת התהליך הזה באמצעות chrome.processing.terminate() או ממשק GUI של מנהל התהליך של Chrome משביתה לא רק את קובץ השירות, אלא גם את דפי התוסף.

בסופו של דבר, ביצענו בדיקה שבודקת כיצד הקוד שלנו מגיב להשעיה של קובץ שירות (service worker) על ידי פתיחת chrome://serviceworker-internals/ ב-Seleenium WebDriver וללחיצה על לחצן העצירה עבור Service Worker.

זו האפשרות הטובה ביותר עד עכשיו, אבל היא לא אידיאלית בגלל שבדיקות Mocha שלנו (שמריצים בדף של תוסף) לא יכולות לעשות זאת בעצמן, לכן הן צריכות ליצור קשר שוב עם תוכנית הצומת של WebDriver. כלומר, לא ניתן להריץ את הבדיקות האלה רק באמצעות התוסף. צריך להפעיל אותן באמצעות Selenium WebDriver.

בהמשך מוצג תרשים שממחיש איך אנחנו מתקשרים עם ה-API של הדפדפן בתהליכי עבודה שונים, ואיך הוספה של המנגנון של השהיית עובדי שירות (service worker) משפיעה עליו.

תרשים של תהליך הבדיקה
תהליך הבדיקה עם השעיה של קובץ השירות (service worker).

בתהליך חדש המשעה את ה-Service Workers (בכחול), הוספנו את Selenium WebDriver לתכונת ה'לחיצה' שתשעה דרך ממשק המשתמש, ופעולה זו מפעילה פעולה בממשק ה-API של הדפדפן.

חשוב לציין שהיה באג ב-Chrome שבו הפעולה הזו עם Selenium WebDriver גרמה ל-Service Worker לא להיות מסוגל להפעיל שוב. השגיאה תוקנה בגרסה 116 של Chrome, ולשמחתנו יש גם פתרון עקיף: הגדרת Chrome לפתיחת כלי הפיתוח באופן אוטומטי בכל כרטיסייה גורמת ל-Service Worker להתחיל לפעול בצורה תקינה.

זו הגישה שבה אנחנו משתמשים בזמן הבדיקה, למרות שהיא לא אידאלית, כי ייתכן שלחיצה על הלחצן לא תהיה ממשק API יציב ופתיחת כלי הפיתוח (בדפדפנים ישנים יותר) כנראה כרוכה בעלות ביצועים.

איך אנחנו מכסים את כל הפונקציונליות? מבחני פאז

אחרי שהיה לנו מנגנון לבדיקת השעייה, היה עלינו להחליט איך לחבר אותו לחבילות של בדיקות האוטומציה. מריצים את הבדיקות הסטנדרטיות שלנו בסביבה שבה לפני כל אינטראקציה עם דף הרקע, ה-service worker הושעה על ידי WebDriver בלחיצה על Stop בדף chrome://serviceworker-internals/.

הרצת בדיקת fuzz לדוגמה
תמונה שמציגה את ההגדרה הנוכחית של הבדיקות.

אנחנו מבצעים את רוב הבדיקות ולא את כולן, כי מנגנון ההשעיה אינו יציב לגמרי ולפעמים הוא גורם לחוסר יציבות. כמו כן, הפעלת כל חבילות הבדיקה במצב fuzz לוקחת זמן רב. לכן, במקום להתייחס לכל המקרים ה "דומים", בחרנו את הנתיבים הקריטיים ביותר לבדיקה במצב fuzz. חשוב לציין שהרצת בדיקות פונקציונליות במצב "fuzz" פירושה שנאלצנו להאריך את הזמן הקצוב לתפוגה של הבדיקות, כי השעיה והפעלה מחדש של קובצי שירות (service worker) נמשכות יותר זמן.

הבדיקות האלה חשובות כי השעיה של קובץ שירות (service worker) מתבצעת בפירוט, כי היא מדגישה מקומות רבים שבהם הקוד נכשל, אבל לא בהכרח חושפת את כל הדרכים העדינות שבהן השעיה של Service Worker עלולה לגרום לשיבושים.

אנחנו מכנים את הבדיקות האלה באופן פנימי 'בדיקות Fuzz'. בדרך כלל, בדיקת fuzz מתבצעת כאשר מזינים קלט לא חוקי בתוכנית ומוודאים שהתגובה שמתקבלת היא סבירה, או לפחות לא קורסת. במקרה שלנו, "קלט לא חוקי" מתייחס להשעיה של קובץ השירות (service worker) בכל עת, ו "התנהגות סבירה" אנחנו מצפים שפונקציונליות סינון המודעות שלנו תמשיך לפעול כרגיל. זה לא קלט לא תקין כי זו התנהגות צפויה במניפסט מגרסה V3, אבל זה היה לא תקין במניפסט מגרסה 2, ולכן נראה שמדובר בטרמינולוגיה סבירה.

סיכום

קובץ שירות (service worker) הוא אחד מהשינויים הגדולים ביותר במניפסט V3 (מלבד כללי declarativeNetRequest). יכול להיות שכדי לעבור למניפסט מגרסה V3 יידרשו שינויים רבים בקוד של תוספי הדפדפן וגישות חדשות לבדיקה. כמו כן, מפתחי תוספים עם מצב קבוע נדרשים להכין את התוספים שלהם לטיפול בהשעיה לא צפויה של קובץ השירות (service worker).

לצערי אין ממשק API לטיפול בהשעיה בדרך פשוטה שמתאימה לתרחיש לדוגמה שלנו. רצינו לבחון את היעילות של בסיס הקוד של התוסף שלנו מול מנגנוני השעיה בשלב מוקדם, ולכן נאלצנו לנסות לפתור את הבעיה. מפתחי תוספים אחרים שמתמודדים עם אתגרים דומים יכולים להשתמש בפתרון הזה. פתרון זה משתלם, למרות שהוא צורך זמן רב בשלב הפיתוח והתחזוקה כדי שנוכל להבטיח שהתוספים שלנו יוכלו לפעול בהצלחה בסביבה שבה עובדי השירות מושעים באופן קבוע.

למרות שכבר יש תמיכה בסיסית בבדיקת השעיה של Service Worker, אנחנו מאוד רוצים לקבל תמיכה טובה יותר בפלטפורמה כדי לבדוק קובצי שירות (service worker) מתוך תוספים בעתיד, כי היא עשויה לקצר משמעותית את זמני הביצוע של הבדיקות ואת מאמצי התחזוקה.