تصور کنید یک تغییر کوچک در نام یک کلاس CSS، تمام تستهای اتوماسیون شما را به رنگ قرمز درآورد و ساعتها وقت تیم QA را برای اصلاح دستی بگیرد. این سناریو منجر به ایجاد مشکل رایج «تستهای شکننده» (Brittle Tests) میشود. برای پایان دادن به این کابوس، یک لایه خودبهبود (Self-healing) سفارشی برای Playwright توسعه یافته است که شکستها را در لحظه مدیریت میکند.
به نقل از گزارشی در ۲۳ جولای ۲۰۲۶ در وبسایت dev.to، این سامانه مانند یک بازرس هوشمند عمل میکند که وقتی یک مکانیاب (Locator) شکست میخورد، بهجای متوقف کردن کل فرآیند، سلسلهمراتبی از استراتژیهای جایگزین را برای نجات تست در زمان واقعی (Real-time) به کار میگیرد.
در چرخههای توسعه چابک (Agile)، عناصر رابط کاربری مدام تغییر میکنند. وقتی برنامهنویسی ساختار DOM یا نام یک کلاس را آپدیت میکند، تستهای سنتی فوراً میشکنند. این وضعیت یک بار نگهداری (Maintenance Burden) ایجاد میکند که در آن مهندسان QA زمان بیشتری را صرف «تعمیر مکانیابها» میکنند تا بررسی ویژگیهای جدید. با معرفی این لایه بهبود به کمک هوش مصنوعی، وابستگی پیشفرض به یک انتخابگر (Selector) تک، ایستا و سختافزاری حذف میشود. همانطور که در تحلیلهای پیشین ما دربارهی پایداری زیرساختهای CI/CD اشاره کردیم، حذف نقاط شکست تکنقطهای در تستها، سرعت انتشار محصول را بهطور مستقیم افزایش میدهد.
زمینه و انگیزه توسعه
این پروژه از یک چرخش در نقشهای حرفهای متولد شد. نویسنده که مسئولیتهایش از QA سنتی به برنامهریزی تغییر کرده بود و بخش بزرگی از اتوماسیون را به هوش مصنوعی زاینده (Generative AI) — مانند دستیاری که کدها را مینویسد اما نیاز به نظارت دارد — سپرده بود، میخواست مهارتهای فنیاش را تیز و بهروز نگه دارد. این رویکرد در واقع بازتابی از تغییر تعریف «کد خوب» از منطق برنامهنویسی به قابلیت نگهداری AI است که در آن تمرکز از نگارش خط به خط کد به مدیریت خروجیهای هوشمند تغییر یافته است. او پس از مشورت با Claude برای یافتن ایدههایی جهت حفظ دانش فنی بدون نیاز به کدنویسی مداوم و حجیم، ایده ساخت این Wrapper برای Playwright را پیاده کرد. این مسیر یادگیری و تعامل با مدلهای زبانی، یادآور چارچوب 4D برای تبدیل کاربر به متخصص هوش مصنوعی است که بر افزایش تسلط بر ابزارهای AI متمرکز است.
هدف نهایی، رسیدگی به ناپایداری تستها در پروژههایی است که در حال حاضر تحت توسعه فعال و تحول ساختاری هستند. وقتی مکانیابها آپدیت شده یا تغییر میکنند، این سیستم مانع از شکست فوری تست میشود. این امر اجازه میدهد اجرای تست ادامه یابد در حالی که همزمان، وقوع شکست در گزارشها مستند میشود.
مکانیزم بازیابی و نجات
قلب تپنده این معماری کلاس SelfHealingPage است. این کلاس منطق بهبود را مدیریت میکند و سعی میکند مکانیاب مشخص شده را واکشی کند. فرآیند با یک تلاش استاندارد و با مهلت زمانی (Timeout) ۳۰۰۰ میلیثانیهای شروع میشود:
const locator = this.page.locator(selector);try { await locator.waitFor({ timeout: 3000 }); return locator; }
اگر مکانیاب وجود نداشته باشد، سیستم خطا را شکار (Catch) کرده و یک هشدار ثبت میکند: [SelfHealing] Selector failed: "{selector}". Trying alternative strategies.... سپس یک SelectorContext حاوی مکانیاب اصلی و هرگونه راهنمایی (Hint) ارائهشده ایجاد شده و به HealingEngine ارسال میشود.
استراتژیهای بازیابی از پایدارترین به شکنندهترین رتبهبندی شدهاند تا اطمینان حاصل شود که بازیابی قابلاعتماد است:
- data-testid (تطبیق فازی): بالاترین اولویت؛ چون یک صفت معنایی (Semantic) است و کمترین نوسان را دارد.
- aria-label: بر اساس استانداردهای دسترسیپذیری (Accessibility) است و عموماً پایدار باقی میماند.
- placeholder: بهویژه در فیلدهای فرم بسیار پایدار است.
- alt text: برای عناصر تصویری (Image elements) قابلاتکا است.
- role + name: معنایی است و بر اساس رفتار عنصر عمل میکند.
- متن قابل مشاهده (Visible text): برای دکمهها و لینکها خوب عمل میکند، هرچند کمی بیشتر در معرض تغییر است.
- موقعیت نسبی (Relative position): آخرین و شکنندهترین راهکار که تنها زمانی استفاده میشود که سایر روشها شکست بخورند.
ارکستراسیون فنی
مسئولیت مدیریت اجرایی بر عهده HealingEngine است. این موتور در سازنده (Constructor) خود، آرایه SelectorStrategy را بر اساس اولویت مرتب میکند تا مطمئن شود مطمئنترین روشها ابتدا امتحان میشوند: this.strategies = [...strategies].sort((a, b) => a.priority - b.priority);.
وقتی متد heal() فراخوانی میشود، موتور روی این استراتژیها پیمایش میکند. یک بررسی حیاتی روی تعداد عناصر با استفاده از await locator.count() انجام میشود. اگر تعداد دقیقاً ۱ باشد، بازیابی موفقیتآمیز است. اما اگر بیش از یک تطابق پیدا شود، موتور برای جلوگیری از تعامل با عنصر اشتباه، نتیجه را رد کرده و به سراغ استراتژی بعدی میرود.

پس از یافتن تطبیق موفق، یک HealingResult شامل مکانیاب، استراتژی استفاده شده و برچسب زمانی (Timestamp) بازگردانده میشود. این رویداد توسط کلاس HealingLog در قالب یک گزارش JSON در پوشه reports/ ذخیره میگردد. مدل دادهای این گزارش شامل موارد زیر است:
- totalAttempts: تعداد کل تلاشها برای بازیابی.
- healed: تعداد بازیابیهای موفق.
- failed: تعداد کل شکستها.
- healingRate: درصد موفقیت بازیابی (مثلاً "100.0%").
- entries: آرایهای از اشیایی که
originalSelector(مکانیاب اصلی)،newSelector(مکانیاب جدید)،strategyUsed(استراتژی استفاده شده) وtimestamp(مثلاً "2026-07-23T20:32:30.359Z") را مستند میکنند.
نقشه معماری پروژه
پروژه برای مقیاسپذیری به ساختاری ماژولار تقسیم شده است:
src/core/:SelfHealingPage.ts: Wrapper اصلی.HealingEngine.ts: ارکستراتور استراتژیها.HealingLog.ts: مدیریت سوابق بهبود و گزارشها.createSelfHealingPage.ts: کارخانه (Factory) یکپارچهساز.
src/strategies/:- فایلهای مجزا برای هر استراتژی:
DataTestIdStrategy.ts,AriaLabelStrategy.ts,PlaceHolderStrategy.ts,AltTextStrategy.ts,RoleStrategy.ts,TextContentStrategy.ts, وRelativePositionStrategy.ts.
- فایلهای مجزا برای هر استراتژی:
src/types/:index.ts: تعریف متمرکز انواع دادهها (Types).
tests/:example.spec.ts: تستهای عملکردی.healing.spec.ts: تستهای مخصوص خودِ فریمورک.
reports/:healing-log.json: فایل نتایج زمان اجرا.
کاربرد در دنیای واقعی
برای اعتبارسنجی فریمورک، این ابزار روی پلتفرم Saucedemo اعمال شد. در یک مورد تست خاص، از یک مکانیاب شکسته [data-test="wrong-login-btn"] استفاده شد تا شکست اجباری ایجاد شود. با این حال، یک راهنمای برچسب (labelHint) با مقدار 'Login' به Wrapper ارائه شد: await shPage.click('[data-test="wrong-login-btn"]', { labelHint: 'Login' });.
علیرغم شناسه (ID) نادرست، HealingEngine از راهنما برای یافتن دکمه صحیح استفاده کرد و اجازه داد تست به صفحه محصولات (Products page) برسد. سپس تست تأیید کرد که HealingLog حاوی ورودی است که در آن مقدار healed برابر با True بوده و مکانیاب اصلی با همان شناسه شکسته مطابقت دارد.
تحلیل تغییر رویکرد
این روش نقش مهندس QA را از «تعمیرکار دستی اسکریپت» به «معمار سامانه» تغییر میدهد. با تمرکز بر نرخ بازیابی بهجای معیارهای دوتایی (پاس/فیل)، تیمها میتوانند نوسانات UI را کمّی کنند. اگر یک مکانیاب مدام توسط سیستم بهبود یابد، این یک سیگنال برای تیم توسعه است تا یک پیادهسازی دائمی data-testid در کد منبع قرار دهند.
برای توسعهدهندگان، این مکانیزم «ناپایداری» (Flakiness) خط لولههای CI/CD را کاهش میدهد. بهجای اینکه یک Merge Request بهدلیل تغییر نام یک کلاس CSS مسدود شود، تست تکمیل شده و تیم گزارشی درباره موارد نیازمند بهروزرسانی دریافت میکند. این یعنی انتقال از «اصلاح واکنشی» به «پایش پیشدستانه پایداری».
نقشه راه آینده
نویسنده اشاره کرده که هرچند بخش اول (بهبود مکانیابهای شکسته) کامل شده، اما چندین بهبود برای عبور از بازیابی واکنشی برنامهریزی شده است. او خاطرنشان کرد که اگرچه ننوشتن تکتک خطوط کد گاهی ناامیدکننده بود، اما فضای بیشتری برای تفکر درباره گسترش معماری فراهم کرد.
بهبودهای کلیدی برنامهریزی شده عبارتند از:
- گزارشدهی پایدار: انتقال از JSON محلی به یک پایگاهداده برای بازاستفاده از مکانیابهای بهبودیافته در اجراهای روزانه خط لوله CI/CD و درخواستهای ادغام (Merge Requests).
- ردیابی متریکها: استفاده از پایگاهداده برای شناسایی مکانیابهایی که مکرراً بهبود مییابند تا درباره اصلاحات دائمی UI با تیم توسعه بحث شود.
- یکپارچگی با فریمورک: پیادهسازی Playwright fixtures برای ارائه خودکار
SelfHealingPageو حذف نیاز به نمونهسازی دستی در هر تست. - پیشبینی با هوش مصنوعی: ثبت اسنپشاتهای DOM در لحظه وقوع حوادث بازیابی برای ساخت یک مجموعه داده (Dataset). این دادهها برای آموزش یک مدل AI استفاده میشوند تا بتواند مکانیاب درست را پیش از وقوع شکست پیشبینی کند.
- توزیع: بستهبندی پروژه به عنوان یک npm package تا سایر تیمها بتوانند آن را در زنجیره ابزارهای داخلی خود به کار گیرند.
توسعهدهندگان علاقهمند به پیادهسازی این روش میتوانند راهکار کامل را در GitHub بررسی کنند تا آن را به ابزاری قابل استفاده مجدد برای پروژههای خود تبدیل نمایند.
گام بعدی شما
- اگر تستهای E2E شما بهدلیل تغییرات UI زیاد میشکنند، ساختار
SelfHealingPageرا برای جداسازی منطق بازیابی از منطق تست بررسی کنید. - برای کاهش هزینه نگهداری تستها، استراتژی
data-testidرا به عنوان استاندارد اول در تیم توسعه معرفی کنید. - گزارشهای JSON تولید شده را به داشبورد معیارهای کیفی پروژه متصل کنید تا نقاط ناپایدار UI شناسایی شوند.
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای Blackwell مراجعه کنید.




گفتگو