برنامه‌های افزودنی Chrome: سفر eyeo به آزمایش تعلیق کارگر خدمات

این در مورد چیست؟

انتقال از Manifest V2 به Manifest V3 با یک تغییر اساسی همراه است. در Manifest V2، برنامه‌های افزودنی در یک صفحه پس‌زمینه زندگی می‌کردند. صفحات پس زمینه ارتباط بین برنامه های افزودنی و صفحات وب را مدیریت می کردند. Manifest V3 به جای آن از سرویس‌کاران استفاده می‌کند.

در این پست به مشکل تست کارکنان خدمات ترویجی می پردازیم. به طور خاص، ما نگاهی می اندازیم به این که چگونه مطمئن شویم که در صورت تعلیق یک کارگر خدماتی، محصول ما به درستی کار می کند.

ما که هستیم؟

eyeo شرکتی است که به توانمندسازی تبادل ارزش آنلاین متعادل و پایدار برای کاربران، مرورگرها، تبلیغ‌کنندگان و ناشران اختصاص دارد. ما بیش از 300 میلیون کاربر جهانی فیلترینگ تبلیغات داریم که به نمایش آگهی‌های قابل قبول اجازه می‌دهند، یک استاندارد تبلیغاتی مشتق شده مستقل که تعیین می‌کند آیا یک تبلیغ قابل قبول است یا نه.

تیم Extension Engine ما فناوری فیلترینگ تبلیغاتی را ارائه می‌کند که برخی از محبوب‌ترین افزونه‌های مرورگر مسدودکننده تبلیغات در بازار مانند AdBlock و Adblock Plus با بیش از 110 میلیون کاربر در سراسر جهان را تامین می‌کند. علاوه بر این، ما این فناوری را به‌عنوان یک کتابخانه منبع باز ارائه می‌کنیم و آن را برای سایر برنامه‌های افزودنی مرورگر فیلترکننده تبلیغات در دسترس قرار می‌دهیم.

کارگر خدماتی چیست؟

کارگران خدمات افزونه، کنترل کننده رویداد مرکزی یک برنامه افزودنی مرورگر هستند. آنها به طور مستقل در پس زمینه اجرا می شوند. به طور کلی این خوب است. ما می توانیم بیشتر کارهایی را که باید در صفحه پس زمینه در سرویس کارگر جدید انجام دهیم. اما تغییرات کمی در مقایسه با صفحات پس زمینه وجود دارد:

  • کارگران خدماتی زمانی که استفاده نمی شوند پایان می دهند . این امر مستلزم آن است که به جای تکیه بر متغیرهای سراسری ، حالت های برنامه را حفظ کنیم . این بدان معناست که هر نقطه ورودی به سیستم ما باید قبل از شروع اولیه سیستم برای فراخوانی آماده شود.
  • شنونده‌های رویداد باید قبل از انتظار برای تماس‌های غیرهمگام‌سازی متصل شوند . کارکنان خدمات معلق همچنان می توانند رویدادهایی را که در آنها مشترک شده است دریافت کنند. اگر شنونده رویداد در اولین دور حلقه رویداد ثبت نشده باشد، اگر آن رویداد سرویس‌کار را بیدار کند، رویداد را دریافت نخواهد کرد.
  • خاتمه بیکاری می تواند تایمرها را قبل از تکمیل قطع کند .

کارگران خدماتی چه زمانی تعلیق می شوند؟

برای Chrome 119، آنچه ما تجربه کرده‌ایم این است که کارکنان خدمات به حالت تعلیق درآمده‌اند:

  • پس از عدم دریافت رویدادها یا تماس با APIهای برنامه افزودنی به مدت 30 ثانیه.
  • اگر ابزارهای برنامه‌نویس باز هستند یا از کتابخانه آزمایشی مبتنی بر ChromeDriver استفاده می‌کنید، هرگز ( به درخواست ویژگی مراجعه کنید ).
  • اگر روی Stop در chrome://serviceworker-internals کلیک کنید.

برای اطلاعات جدیدتر به چرخه حیات کارگران خدمات مراجعه کنید.

چرا تست این مشکل دارد؟

در حالت ایده‌آل، داشتن راهنمایی رسمی در مورد «چگونگی آزمایش کارکنان خدمات به روشی کارآمد» یا نمونه‌هایی از آزمون‌های کاری مفید بود. در طول ماجراجویی‌هایمان در آزمایش کارکنان خدمات، با چند چالش مواجه شدیم:

  • ما در پسوند آزمون خود حالت داریم. وقتی سرویس کار متوقف می شود، وضعیت و رویدادهای ثبت شده آن را از دست می دهیم. چگونه داده ها را در جریان آزمایش خود نگه داریم؟
  • اگر می‌توان سرویس‌کاران را در هر نقطه‌ای به حالت تعلیق درآورد، باید آزمایش کنیم که همه ویژگی‌ها در صورت قطع شدن کار می‌کنند.
  • حتی اگر مکانیزمی را در آزمایش‌های خود معرفی کنیم که به‌طور تصادفی کارکنان خدمات را به حالت تعلیق در می‌آورد، هیچ API در مرورگر وجود ندارد که به راحتی آن را تعلیق کند. ما از تیم W3C خواسته ایم که این ویژگی را اضافه کند، اما این یک گفتگوی مداوم است.

تعلیق کارگر خدمات تست

ما چندین روش را برای فعال کردن تعلیق کارکنان خدمات در طول آزمایشات امتحان کرده ایم:

رویکرد مسائل مربوط به رویکرد
مدت زمان دلخواه (مثلا 30 ثانیه) صبر کنید این امر باعث کندی و غیرقابل اعتماد بودن تست می شود، به خصوص در هنگام اجرای چندین تست. هنگام استفاده از WebDriver کار نمی‌کند، زیرا WebDriver از API DevTools Chrome استفاده می‌کند و وقتی DevTools باز است، سرویس‌کار معلق نمی‌شود. حتی اگر بتوانیم آن را دور بزنیم، باز هم باید بررسی کنیم که آیا کارمند خدمات تعلیق شده است و راهی برای این کار نداریم.
یک حلقه بی نهایت در سرویس کار اجرا کنید با توجه به مشخصات، بسته به نحوه اجرای این قابلیت توسط مرورگر، این می تواند منجر به خاتمه شود. Chrome در این مورد سرویس‌کار را خاتمه نمی‌دهد، بنابراین ما نمی‌توانیم این سناریو را زمانی که سرویس‌کار معلق می‌شود آزمایش کنیم.
داشتن پیامی در سرویس‌کار برای بررسی تعلیق بودن آن با ارسال پیام، کارمند خدمات بیدار می شود. از این می‌توان برای بررسی اینکه آیا سرویس‌کار خواب بوده است یا خیر، استفاده می‌شود، اما نتایج آزمایش‌هایی را که باید بلافاصله پس از تعلیق سرویس‌کار بررسی شود، خراب می‌کند.
با استفاده از () chrome.processes.terminate، فرآیند service worker را بکشید سرویس‌کار برای برنامه افزودنی فرآیندی را با سایر بخش‌های برنامه افزودنی به اشتراک می‌گذارد، بنابراین از بین بردن این فرآیند با استفاده از chrome.process.terminate() یا رابط کاربری گرافیکی مدیر فرآیند Chrome نه تنها کارمند سرویس، بلکه هر صفحه افزونه را نیز از بین می‌برد.

ما به آزمایشی رسیدیم که بررسی می‌کند چگونه کد ما به حالت تعلیق شدن سرویس‌دهنده پاسخ می‌دهد، با باز کردن Selenium WebDriver chrome://serviceworker-internals/ و کلیک روی دکمه «توقف» برای سرویس‌کار.

این بهترین گزینه تا کنون است، اما ایده‌آل نیست زیرا تست‌های Mocha ما (که در یک صفحه افزونه اجرا می‌شوند) خودشان نمی‌توانند این کار را انجام دهند، بنابراین باید به برنامه گره WebDriver ما ارتباط برقرار کنند. این بدان معناست که این آزمایش ها نمی توانند فقط با استفاده از برنامه افزودنی اجرا شوند. آنها باید با استفاده از Selenium WebDriver فعال شوند.

در اینجا نموداری از نحوه ارتباط ما با API مرورگر از طریق جریان‌های مختلف و چگونگی تأثیر افزودن مکانیسم «تعلیق کارگران سرویس» بر آن است.

نموداری که جریان آزمایش را نشان می دهد
جریان آزمایش با تعلیق کارگر خدمات.

در جریان جدیدی که سرویس‌کاران را به حالت تعلیق در می‌آورد (آبی)، ما Selenium WebDriver را اضافه کرده‌ایم تا روی تعلیق «کلیک» از طریق UI انجام شود، که باعث ایجاد یک عمل در API مرورگر می‌شود.

شایان ذکر است که یک باگ کروم وجود داشت که انجام این کار با Selenium WebDriver باعث می شد که سرویس دهنده قادر به راه اندازی مجدد نباشد. این مشکل در Chrome 116 برطرف شد و خوشبختانه یک راه‌حل نیز وجود دارد: تنظیم Chrome برای باز کردن خودکار DevTools در هر برگه باعث می‌شود سرویس‌کار به درستی شروع به کار کند.

این رویکردی است که ما هنگام آزمایش از آن استفاده می‌کنیم، اگرچه ایده‌آل نیست زیرا کلیک کردن روی دکمه ممکن است یک API پایدار نباشد و باز کردن DevTools (برای مرورگرهای قدیمی‌تر) هزینه عملکردی دارد.

چگونه کل عملکرد را پوشش دهیم؟ تست های فازی

هنگامی که مکانیزمی برای تست تعلیق داشتیم، باید تصمیم می گرفتیم که چگونه آن را به مجموعه تست اتوماسیون خود متصل کنیم. ما آزمایش‌های استاندارد خود را در محیطی اجرا کردیم که قبل از هر تعامل با صفحه پس‌زمینه، سرویس‌کار با کلیک روی توقف در صفحه chrome://serviceworker-internals/ WebDriver به حالت تعلیق در می‌آید .

نمونه اجرای آزمایش فازی
تصویری که تنظیمات فعلی آزمایش ها را ارائه می دهد.

ما اکثر و نه همه آزمایش ها را انجام می دهیم زیرا مکانیسم تعلیق کاملاً پایدار نیست و گاهی اوقات باعث پوسته پوسته شدن می شود. همچنین اجرای تمامی مجموعه های آزمایشی در حالت فازی زمان زیادی می برد. بنابراین، به جای پوشش همه موارد "مشابه"، ما بحرانی ترین مسیرها را برای آزمایش در حالت فازی انتخاب کردیم. شایان ذکر است که اجرای تست های عملکردی در حالت "فازی" به این معنی است که ما مجبور شدیم تایم اوت تست ها را افزایش دهیم زیرا تعلیق و راه اندازی مجدد کارگران خدمات زمان بیشتری را می طلبد.

این تست‌ها به‌عنوان یک پاس اول درشت دانه ارزشمند هستند، که بسیاری از مکان‌های شکست کد را مشخص می‌کند، اما ممکن است لزوماً همه راه‌های ظریفی را که تعلیق کارگر خدمات ممکن است باعث شکسته شدن چیزها شود، آشکار نکند.

در داخل به این نوع آزمون ها «تست فاز» می گوییم. به طور سنتی، تست فاز زمانی است که ورودی نامعتبر را به برنامه خود وارد می‌کنید و مطمئن می‌شوید که به طور منطقی پاسخ می‌دهد، یا حداقل خراب نمی‌شود. در مورد ما، «ورودی نامعتبر» عبارت است از تعلیق کارگر سرویس در هر زمان، و «رفتار معقولی» که ما انتظار داریم این است که عملکرد فیلترینگ تبلیغات ما باید مانند گذشته به کار خود ادامه دهد. این واقعاً ورودی نامعتبر نیست زیرا این رفتار مورد انتظار در Manifest V3 است، اما در Manifest V2 نامعتبر بوده است بنابراین اصطلاحات منطقی به نظر می رسد.

خلاصه

کارگران خدمات یکی از بزرگترین تغییرات در Manifest V3 هستند (علاوه بر قوانین دکلراتیو NetRequest). انتقال به Manifest V3 ممکن است نیاز به تغییرات زیادی در کد در پسوند مرورگر و رویکردهای جدید برای آزمایش داشته باشد. همچنین از توسعه‌دهندگان برنامه‌های افزودنی با حالت پایدار می‌خواهد که برنامه‌های افزودنی خود را برای مدیریت تعلیق غیرمنتظره کارکنان خدمات به روشی برازنده آماده کنند.

متأسفانه، هیچ API برای مدیریت تعلیق به روشی آسان و متناسب با مورد استفاده ما وجود ندارد. از آنجایی که می‌خواستیم در مراحل اولیه استحکام پایگاه کد برنامه افزودنی خود را در برابر مکانیسم‌های تعلیق آزمایش کنیم، باید در اطراف آن کار می‌کردیم. سایر توسعه دهندگان برنامه افزودنی که با چالش های مشابهی روبرو هستند می توانند از این راه حل استفاده کنند، که اگرچه در مرحله توسعه و تعمیر و نگهداری وقت گیر است، اما ارزش آن را دارد تا بتوانیم اطمینان حاصل کنیم که برنامه های افزودنی ما می توانند با موفقیت در محیطی کار کنند که در آن کارکنان خدمات به طور منظم معلق هستند.

حتی اگر پشتیبانی اولیه برای تست تعلیق کارگر سرویس وجود داشته باشد، پشتیبانی پلتفرم بهتر برای آزمایش کارکنان خدمات از داخل برنامه‌های افزودنی چیزی است که ما واقعاً دوست داریم در آینده شاهد آن باشیم، زیرا می‌تواند زمان اجرای آزمایش و تلاش تعمیر و نگهداری ما را تا حد زیادی کاهش دهد.