مشغل Storybook لا يزال في المرحلة التجريبية، وسيتم نقل الوثائق لاحقًا إلى صفحات وثائق WebdriverIO.
تدعم هذه الوحدة الآن Storybook مع مشغل Visual جديد. يقوم هذا المشغل تلقائيًا بمسح مثيل Storybook محلي/بعيد وسينشئ لقطات شاشة للعناصر لكل مكون. يمكن القيام بذلك عن طريق إضافة
export const config: WebdriverIO.Config = {
services: ["visual"],
};
إلى services
الخاصة بك وتشغيل npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook
من خلال سطر الأوامر.
سيستخدم Chrome في وضع headless كمتصفح افتراضي.
[!NOTE]
- ستعمل معظم خيارات الاختبار البصري أيضًا مع مشغل Storybook، راجع وثائق WebdriverIO.
- سيقوم مشغل Storybook بتجاوز جميع إمكانياتك ويمكنه التشغيل فقط على المتصفحات التي يدعمها، انظر
--browsers
.
- لا يدعم مشغل Storybook التكوين الحالي الذي يستخدم إمكانيات Multiremote وسيظهر خطأ.
- يدعم مشغل Storybook فقط ويب سطح المكتب، وليس ويب الجوال.
خيارات خدمة مشغل Storybook
يمكن توفير خيارات الخدمة بهذه الطريقة
export const config: WebdriverIO.Config = {
services: [
[
'visual',
{
baselineFolder: join(process.cwd(), './__snapshots__/'),
debug: true,
storybook: {
additionalSearchParams: new URLSearchParams({foo: 'bar', abc: 'def'}),
clip: false,
clipSelector: ''#some-id,
numShards: 4,
skipStories: ['example-button--secondary', 'example-button--small'],
url: 'https://www.bbc.co.uk/iplayer/storybook/',
version: 6,
getStoriesBaselinePath: (category, component) => `path__${category}__${component}`,
},
},
],
],
}
خيارات سطر أوامر مشغل Storybook
--additionalSearchParams
- النوع:
string
- إلزامي: لا
- الافتراضي: ''
- مثال:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --additionalSearchParams="foo=bar&abc=def"
سيضيف معلمات بحث إضافية إلى عنوان URL الخاص بـ Storybook.
راجع وثائق URLSearchParams لمزيد من المعلومات. يجب أن تكون السلسلة عبارة عن سلسلة URLSearchParams صالحة.
[!NOTE]
هناك حاجة إلى علامات الاقتباس المزدوجة لمنع تفسير &
كفاصل أمر.
على سبيل المثال، مع --additionalSearchParams="foo=bar&abc=def"
سيقوم بإنشاء عنوان URL التالي لـ Storybook لاختبار القصص: http://storybook.url/iframe.html?id=story-id&foo=bar&abc=def
.
--browsers
- النوع:
string
- إلزامي: لا
- الافتراضي:
chrome
، يمكنك الاختيار من chrome|firefox|edge|safari
- مثال:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --browsers=chrome,firefox,edge,safari
- ملاحظة: متاح فقط من خلال سطر الأوامر
سيستخدم المتصفحات المقدمة لالتقاط لقطات شاشة للمكونات
[!NOTE]
تأكد من تثبيت المتصفحات التي تريد التشغيل عليها على جهازك المحلي
--clip
- النوع:
boolean
- إلزامي: لا
- الافتراضي:
true
- مثال:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --clip=false
عند تعطيله، سيقوم بإنشاء لقطة شاشة لمنفذ العرض. عند تمكينه، سيقوم بإنشاء لقطات شاشة للعناصر بناءً على --clipSelector
مما سيقلل من كمية المساحة البيضاء حول لقطة شاشة المكون ويقلل من حجم لقطة الشاشة.
--clipSelector
- النوع:
string
- إلزامي: لا
- الافتراضي:
#storybook-root > :first-child
لـ Storybook V7 و #root > :first-child:not(script):not(style)
لـ Storybook V6، انظر أيضًا --version
- مثال:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --clipSelector="#some-id"
هذا هو المحدد الذي سيتم استخدامه:
- لتحديد العنصر الذي سيتم التقاط لقطة الشاشة له
- للعنصر للانتظار ليكون مرئيًا قبل التقاط لقطة شاشة
--devices
- النوع:
string
- إلزامي: لا
- الافتراضي: يمكنك الاختيار من
deviceDescriptors.ts
- مثال:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --devices="iPhone 14 Pro Max","Pixel 3 XL"
- ملاحظة: متاح فقط من خلال سطر الأوامر
سيستخدم الأجهزة المقدمة التي تتطابق مع deviceDescriptors.ts
لالتقاط لقطات شاشة المكونات
[!NOTE]
- إذا كنت تفتقد تكوين جهاز، فلا تتردد في تقديم طلب ميزة
- سيعمل هذا فقط مع Chrome:
- إذا قدمت
--devices
فستعمل جميع نسخ Chrome في وضع محاكاة الجوال
- إذا قدمت أيضًا متصفحات أخرى غير Chrome، مثل
--devices --browsers=firefox,safari,edge
فسيضيف تلقائيًا Chrome في وضع محاكاة الجوال
- سينشئ مشغل Storybook افتراضيًا لقطات عنصر، إذا كنت تريد رؤية لقطة شاشة محاكاة الجوال الكاملة، فقدم
--clip=false
من خلال سطر الأوامر
- سيبدو اسم الملف على سبيل المثال مثل
__snapshots__/example/button/desktop_chrome/example-button--large-local-chrome-iPhone-14-Pro-Max-430x932-dpr-3.png
- المصدر: اختبار موقع ويب للجوال على سطح المكتب باستخدام محاكاة الجوال يمكن أن يكون مفيدًا، ولكن يجب أن يكون المختبرون على دراية بوجود العديد من الاختلافات الدقيقة مثل:
- وحدة معالجة رسومات مختلفة تمامًا، مما قد يؤدي إلى تغييرات كبيرة في الأداء؛
- واجهة مستخدم الجوال غير محاكاة (على وجه الخصوص، يؤثر إخفاء شريط عنوان URL على ارتفاع الصفحة)؛
- نافذة منبثقة للتمييز (حيث تحدد أحد أهداف اللمس القليلة) غير مدعومة؛
- العديد من واجهات برمجة التطبيقات للأجهزة (على سبيل المثال، حدث تغيير الاتجاه) غير متوفرة.
--headless
- النوع:
boolean
- إلزامي: لا
- الافتراضي:
true
- مثال:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --headless=false
- ملاحظة: متاح فقط من خلال سطر الأوامر
هذا سيقوم بتشغيل الاختبارات افتراضيًا في وضع غير مرئي (عندما يدعم المتصفح ذلك) أو يمكن تعطيله
--numShards
- النوع:
number
- إلزامي: لا
- الافتراضي:
true
- مثال:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --numShards=10
سيكون هذا عدد المثيلات المتوازية التي سيتم استخدامها لتشغيل القصص. سيتم تحديد هذا بواسطة maxInstances
في ملف wdio.conf
الخاص بك.
[!IMPORTANT]
عند التشغيل في وضع headless
، لا تزيد العدد إلى أكثر من 20 لمنع عدم الاستقرار بسبب قيود الموارد
--skipStories
- النوع:
string|regex
- إلزامي: لا
- الافتراضي: null
- مثال:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --skipStories="/.*button.*/gm"
يمكن أن يكون هذا:
- سلسلة (
example-button--secondary,example-button--small
)
- أو تعبير منتظم (
"/.*button.*/gm"
)
لتخطي قصص معينة. استخدم id
الخاص بالقصة التي يمكن العثور عليها في عنوان URL للقصة. على سبيل المثال، id
في عنوان URL هذا http://localhost:6006/?path=/story/example-page--logged-out
هو example-page--logged-out
--url
- النوع:
string
- إلزامي: لا
- الافتراضي:
http://127.0.0.1:6006
- مثال:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --url="https://example.com"
عنوان URL حيث يتم استضافة مثيل Storybook الخاص بك.
--version
- النوع:
number
- إلزامي: لا
- الافتراضي: 7
- مثال:
npx wdio tests/configs/wdio.local.desktop.storybook.conf.ts --storybook --version=6
هذا هو إصدار Storybook، الافتراضي هو 7
. هذا مطلوب لمعرفة ما إذا كان يجب استخدام clipSelector
الخاص بـ V6.
اختبار التفاعل في Storybook
يسمح لك اختبار التفاعل في Storybook بالتفاعل مع المكون الخاص بك من خلال إنشاء نصوص مخصصة باستخدام أوامر WDIO لوضع المكون في حالة معينة. على سبيل المثال، انظر إلى مقتطف الكود أدناه:
import { browser, expect } from "@wdio/globals";
describe("Storybook Interaction", () => {
it("should create screenshots for the logged in state when it logs out", async () => {
const componentId = "example-page--logged-in";
await browser.waitForStorybookComponentToBeLoaded({ id: componentId });
await expect($("header")).toMatchElementSnapshot(
`${componentId}-logged-in-state`
);
await $("button=Log out").click();
await expect($("header")).toMatchElementSnapshot(
`${componentId}-logged-out-state`
);
});
it("should create screenshots for the logged out state when it logs in", async () => {
const componentId = "example-page--logged-out";
await browser.waitForStorybookComponentToBeLoaded({ id: componentId });
await expect($("header")).toMatchElementSnapshot(
`${componentId}-logged-out-state`
);
await $("button=Log in").click();
await expect($("header")).toMatchElementSnapshot(
`${componentId}-logged-in-state`
);
});
});
يتم تنفيذ اختبارين على مكونين مختلفين. يقوم كل اختبار أولاً بتعيين حالة ثم يلتقط لقطة شاشة. ستلاحظ أيضًا أنه تم تقديم أمر مخصص جديد، والذي يمكن العثور عليه هنا.
يمكن حفظ ملف المواصفات أعلاه في مجلد وإضافته إلى سطر الأوامر باستخدام الأمر التالي:
pnpm run test.local.desktop.storybook.localhost -- --spec='tests/specs/storybook-interaction/*.ts'
سيقوم مشغل Storybook أولاً بمسح مثيل Storybook الخاص بك تلقائيًا ثم إضافة اختباراتك إلى القصص التي تحتاج إلى مقارنة. إذا كنت لا تريد مقارنة المكونات التي تستخدمها لاختبار التفاعل مرتين، يمكنك إضافة عامل تصفية لإزالة القصص "الافتراضية" من المسح عن طريق توفير عامل تصفية --skipStories
. سيبدو هذا كما يلي:
pnpm run test.local.desktop.storybook.localhost -- --skipStories="/example-page.*/gm" --spec='tests/specs/storybook-interaction/*.ts'
أمر مخصص جديد
سيتم إضافة أمر مخصص جديد يسمى browser.waitForStorybookComponentToBeLoaded({ id: 'componentId' })
إلى كائن browser/driver
الذي سيقوم تلقائيًا بتحميل المكون والانتظار حتى ينتهي، حتى لا تضطر إلى استخدام طريقة browser.url('url.com')
. يمكن استخدامه بهذه الطريقة
import { browser, expect } from "@wdio/globals";
describe("Storybook Interaction", () => {
it("should create screenshots for the logged in state when it logs out", async () => {
const componentId = "example-page--logged-in";
await browser.waitForStorybookComponentToBeLoaded({ id: componentId });
await expect($("header")).toMatchElementSnapshot(
`${componentId}-logged-in-state`
);
await $("button=Log out").click();
await expect($("header")).toMatchElementSnapshot(
`${componentId}-logged-out-state`
);
});
it("should create screenshots for the logged out state when it logs in", async () => {
const componentId = "example-page--logged-out";
await browser.waitForStorybookComponentToBeLoaded({ id: componentId });
await expect($("header")).toMatchElementSnapshot(
`${componentId}-logged-out-state`
);
await $("button=Log in").click();
await expect($("header")).toMatchElementSnapshot(
`${componentId}-logged-in-state`
);
});
});
الخيارات هي:
additionalSearchParams
await browser.waitForStorybookComponentToBeLoaded({
additionalSearchParams: new URLSearchParams({ foo: "bar", abc: "def" }),
id: "componentId",
});
هذا سيضيف معلمات بحث إضافية إلى عنوان URL الخاص بـ Storybook، في المثال أعلاه سيكون عنوان URL http://storybook.url/iframe.html?id=story-id&foo=bar&abc=def
.
راجع وثائق URLSearchParams لمزيد من المعلومات.
clipSelector
- النوع:
string
- إلزامي: لا
- الافتراضي:
#storybook-root > :first-child
لـ Storybook V7 و #root > :first-child:not(script):not(style)
لـ Storybook V6
- مثال:
await browser.waitForStorybookComponentToBeLoaded({
clipSelector: "#your-selector",
id: "componentId",
});
هذا هو المحدد الذي سيتم استخدامه:
- لتحديد العنصر الذي سيتم التقاط لقطة الشاشة له
- للعنصر للانتظار ليكون مرئيًا قبل التقاط لقطة شاشة
- النوع:
string
- إلزامي: نعم
- مثال:
await browser.waitForStorybookComponentToBeLoaded({ '#your-selector', id: 'componentId' })
استخدم id
الخاص بالقصة التي يمكن العثور عليها في عنوان URL للقصة. على سبيل المثال، id
في عنوان URL هذا http://localhost:6006/?path=/story/example-page--logged-out
هو example-page--logged-out
timeout
- النوع:
number
- إلزامي: لا
- الافتراضي: 1100 مللي ثانية
- مثال:
await browser.waitForStorybookComponentToBeLoaded({
id: "componentId",
timeout: 20000,
});
الحد الأقصى للمهلة التي نريد الانتظار حتى يكون المكون مرئيًا بعد التحميل على الصفحة
url
- النوع:
string
- إلزامي: لا
- الافتراضي:
http://127.0.0.1:6006
- مثال:
await browser.waitForStorybookComponentToBeLoaded({
id: "componentId",
url: "https://your.url",
});
عنوان URL حيث يتم استضافة مثيل Storybook الخاص بك.