diff --git a/change/@fluentui-web-components-f10b25db-f9c4-4ce4-a77b-5c3bdf81283e.json b/change/@fluentui-web-components-f10b25db-f9c4-4ce4-a77b-5c3bdf81283e.json
new file mode 100644
index 00000000000000..0da3e221a3ffce
--- /dev/null
+++ b/change/@fluentui-web-components-f10b25db-f9c4-4ce4-a77b-5c3bdf81283e.json
@@ -0,0 +1,7 @@
+{
+ "type": "none",
+ "comment": "chore: use component tag names in playwright tests",
+ "packageName": "@fluentui/web-components",
+ "email": "863023+radium-v@users.noreply.github.com",
+ "dependentChangeType": "none"
+}
diff --git a/packages/web-components/playwright.config.ts b/packages/web-components/playwright.config.ts
index 91b2f75a52d273..dd6a17dc3b0571 100644
--- a/packages/web-components/playwright.config.ts
+++ b/packages/web-components/playwright.config.ts
@@ -8,6 +8,9 @@ const config: PlaywrightTestConfig = {
timeout: process.env.CI ? 10000 : 30000,
use: {
baseURL: 'http://localhost:5173',
+ contextOptions: {
+ reducedMotion: 'reduce',
+ },
},
projects: [
{
@@ -20,7 +23,10 @@ const config: PlaywrightTestConfig = {
},
{
name: 'webkit',
- use: { ...devices['Desktop Safari'] },
+ use: {
+ ...devices['Desktop Safari'],
+ deviceScaleFactor: 1,
+ },
},
],
webServer: {
diff --git a/packages/web-components/src/accordion-item/accordion-item.spec.ts b/packages/web-components/src/accordion-item/accordion-item.spec.ts
index bdfbdd8761a1b4..24c38b413f461e 100644
--- a/packages/web-components/src/accordion-item/accordion-item.spec.ts
+++ b/packages/web-components/src/accordion-item/accordion-item.spec.ts
@@ -1,12 +1,13 @@
import { expect, test } from '../../test/playwright/index.js';
+import { tagName as AccordionTagName } from '../accordion/accordion.options.js';
import { AccordionItem } from './accordion-item.js';
-import { AccordionItemSize } from './accordion-item.options.js';
+import { AccordionItemSize, tagName } from './accordion-item.options.js';
test.describe('Accordion item', () => {
test.use({
innerHTML: 'Hello, World!',
- tagName: 'fluent-accordion-item',
- waitFor: ['fluent-accordion-item'],
+ tagName,
+ waitFor: [AccordionTagName],
});
test('should create with document.createElement()', async ({ page, fastPage }) => {
@@ -18,9 +19,9 @@ test.describe('Accordion item', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-accordion-item');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -29,12 +30,12 @@ test.describe('Accordion item', () => {
const { element } = fastPage;
await fastPage.setTemplate(/* html */ `
-
-
+ <${AccordionTagName}>
+ <${tagName}>
Heading 1
Content 1
-
-
+ ${tagName}>
+ ${AccordionTagName}>
`);
await expect(element).toHaveJSProperty('headinglevel', 2);
@@ -78,7 +79,7 @@ test.describe('Accordion item', () => {
fastPage,
}) => {
const { element } = fastPage;
- const button = fastPage.element.locator('button');
+ const button = element.locator('button');
await fastPage.setTemplate({ attributes: { disabled: true } });
@@ -95,11 +96,11 @@ test.describe('Accordion item', () => {
const { element } = fastPage;
await fastPage.setTemplate(/* html */ `
-
- Item 1
- Item 2
- Item 3
-
+ <${AccordionTagName}>
+ <${tagName}>Item 1${tagName}>
+ <${tagName} disabled>Item 2${tagName}>
+ <${tagName}>Item 3${tagName}>
+ ${AccordionTagName}>
`);
const firstItem = element.nth(0);
const secondItem = element.nth(1);
diff --git a/packages/web-components/src/accordion/accordion.spec.ts b/packages/web-components/src/accordion/accordion.spec.ts
index 679ca8713b291a..1c6ce16e4a0758 100644
--- a/packages/web-components/src/accordion/accordion.spec.ts
+++ b/packages/web-components/src/accordion/accordion.spec.ts
@@ -1,9 +1,21 @@
import { expect, test } from '../../test/playwright/index.js';
+import { tagName as AccordionItemTagName } from '../accordion-item/accordion-item.options.js';
+import { tagName } from './accordion.options.js';
test.describe('Accordion', () => {
test.use({
- innerHTML: 'Hello, World!',
- tagName: 'fluent-accordion',
+ tagName,
+ innerHTML: /* html */ `
+ <${AccordionItemTagName} tabindex="0">
+ Heading 1
+
Content 1
+ ${AccordionItemTagName}>
+ <${AccordionItemTagName} tabindex="0">
+ Heading 2
+ Content 2
+ ${AccordionItemTagName}>
+ `,
+ waitFor: [AccordionItemTagName],
});
test('should create with document.createElement()', async ({ page, fastPage }) => {
@@ -15,9 +27,9 @@ test.describe('Accordion', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-accordion');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -27,16 +39,6 @@ test.describe('Accordion', () => {
await fastPage.setTemplate({
attributes: { 'expand-mode': 'multi' },
- innerHTML: /* html */ `
-
- Heading 1
- Content 1
-
-
- Heading 2
- Content 2
-
- `,
});
await expect(element).toHaveAttribute('expand-mode', 'multi');
@@ -44,22 +46,12 @@ test.describe('Accordion', () => {
test('should open/close appropriate accordion items on Enter key in single expand mode', async ({ fastPage }) => {
const { element } = fastPage;
- const accordionItems = element.locator('fluent-accordion-item');
+ const accordionItems = element.locator(AccordionItemTagName);
const firstItem = accordionItems.nth(0);
const secondItem = accordionItems.nth(1);
await fastPage.setTemplate({
attributes: { 'expand-mode': 'single' },
- innerHTML: /* html */ `
-
- Heading 1
- Content 1
-
-
- Heading 1
- Content 1
-
- `,
});
await expect(firstItem).toHaveAttribute('expanded');
@@ -81,22 +73,12 @@ test.describe('Accordion', () => {
test('should open/close appropriate accordion items on Enter key in multi expand mode', async ({ fastPage }) => {
const { element } = fastPage;
- const accordionItems = element.locator('fluent-accordion-item');
+ const accordionItems = element.locator(AccordionItemTagName);
const firstItem = accordionItems.nth(0);
const secondItem = accordionItems.nth(1);
await fastPage.setTemplate({
attributes: { 'expand-mode': 'multi' },
- innerHTML: /* html */ `
-
- Heading 1
- Content 1
-
-
- Heading 1
- Content 1
-
- `,
});
await expect(firstItem).toHaveJSProperty('expanded', false);
@@ -124,16 +106,6 @@ test.describe('Accordion', () => {
const { element } = fastPage;
await fastPage.setTemplate({
attributes: { 'expand-mode': 'single' },
- innerHTML: /* html */ `
-
- Heading 1
- Content 1
-
-
- Heading 2
- Content 2
-
- `,
});
await expect(element).toHaveAttribute('expand-mode', 'single');
@@ -144,18 +116,7 @@ test.describe('Accordion', () => {
}) => {
const { element } = fastPage;
- await fastPage.setTemplate({
- innerHTML: /* html */ `
-
- Heading 1
- Content 1
-
-
- Heading 2
- Content 2
-
- `,
- });
+ await fastPage.setTemplate();
await expect(element).toHaveJSProperty('expandmode', 'multi');
@@ -164,20 +125,10 @@ test.describe('Accordion', () => {
test('should expand/collapse items when clicked in multi mode', async ({ fastPage }) => {
const { element } = fastPage;
- const items = element.locator('fluent-accordion-item');
+ const items = element.locator(AccordionItemTagName);
await fastPage.setTemplate({
attributes: { 'expand-mode': 'multi' },
- innerHTML: /* html */ `
-
- Heading 1
- Content 1
-
-
- Heading 2
- Content 2
-
- `,
});
await items.nth(0).click();
@@ -191,22 +142,12 @@ test.describe('Accordion', () => {
test('should only have one expanded item in single mode', async ({ fastPage }) => {
const { element } = fastPage;
- const items = element.locator('fluent-accordion-item');
+ const items = element.locator(AccordionItemTagName);
const firstItem = items.nth(0);
const secondItem = items.nth(1);
await fastPage.setTemplate({
attributes: { 'expand-mode': 'single' },
- innerHTML: /* html */ `
-
- Heading 1
- Content 1
-
-
- Heading 2
- Content 2
-
- `,
});
await firstItem.click();
@@ -229,19 +170,9 @@ test.describe('Accordion', () => {
await fastPage.setTemplate({
attributes: { 'expand-mode': 'single' },
- innerHTML: /* html */ `
-
- Heading 1
- Content 1
-
-
- Heading 2
- Content 2
-
- `,
});
- const items = element.locator('fluent-accordion-item');
+ const items = element.locator(AccordionItemTagName);
const firstItem = items.nth(0);
@@ -272,19 +203,9 @@ test.describe('Accordion', () => {
await fastPage.setTemplate({
attributes: { 'expand-mode': 'single' },
- innerHTML: /* html */ `
-
- Heading 1
- Content 1
-
-
- Heading 2
- Content 2
-
- `,
});
- const items = element.locator('fluent-accordion-item');
+ const items = element.locator(AccordionItemTagName);
const firstItem = items.nth(0);
@@ -310,19 +231,9 @@ test.describe('Accordion', () => {
attributes: {
'expand-mode': 'single',
},
- innerHTML: /* html */ `
-
- Heading 1
- Content 1
-
-
- Heading 2
- Content 2
-
- `,
});
- const items = element.locator('fluent-accordion-item');
+ const items = element.locator(AccordionItemTagName);
const firstItem = items.nth(0);
@@ -347,22 +258,22 @@ test.describe('Accordion', () => {
'expand-mode': 'single',
},
innerHTML: /* html */ `
-
+ <${AccordionItemTagName}>
Heading 1
Content 1
-
-
+ ${AccordionItemTagName}>
+ <${AccordionItemTagName} expanded>
Heading 2
Content 2
-
-
+ ${AccordionItemTagName}>
+ <${AccordionItemTagName} expanded>
Heading 3
Content 2
-
+ ${AccordionItemTagName}>
`,
});
- const items = element.locator('fluent-accordion-item');
+ const items = element.locator(AccordionItemTagName);
const firstItem = items.nth(0);
@@ -385,22 +296,22 @@ test.describe('Accordion', () => {
'expand-mode': 'single',
},
innerHTML: /* html */ `
-
+ <${AccordionItemTagName}>
Heading 1
Content 1
-
-
+ ${AccordionItemTagName}>
+ <${AccordionItemTagName} expanded disabled>
Heading 2
Content 2
-
-
+ ${AccordionItemTagName}>
+ <${AccordionItemTagName} expanded>
Heading 3
Content 2
-
+ ${AccordionItemTagName}>
`,
});
- const items = element.locator('fluent-accordion-item');
+ const items = element.locator(AccordionItemTagName);
const firstItem = items.nth(0);
@@ -431,18 +342,18 @@ test.describe('Accordion', () => {
await fastPage.setTemplate({
attributes: { 'expand-mode': 'single' },
innerHTML: /* html */ `
-
+ <${AccordionItemTagName}>
Accordion Item 1 Heading
Accordion Item 1 Content
-
-
+ ${AccordionItemTagName}>
+ <${AccordionItemTagName}>
Accordion Item 2 Heading
- A checkbox as content
-
+ A checkbox as content
+ ${AccordionItemTagName}>
`,
});
- const item = element.locator('fluent-accordion-item').nth(1);
+ const item = element.locator(AccordionItemTagName).nth(1);
const button = item.locator('button[part="button"]');
@@ -450,7 +361,7 @@ test.describe('Accordion', () => {
await expect(item).toHaveAttribute('expanded');
- const checkbox = item.locator('fluent-checkbox');
+ const checkbox = item.locator('input[type="checkbox"]');
await checkbox.click();
diff --git a/packages/web-components/src/anchor-button/anchor-button.spec.ts b/packages/web-components/src/anchor-button/anchor-button.spec.ts
index f0e0bd22bd21fe..e34999cea9260f 100644
--- a/packages/web-components/src/anchor-button/anchor-button.spec.ts
+++ b/packages/web-components/src/anchor-button/anchor-button.spec.ts
@@ -1,10 +1,10 @@
import { expect, test } from '../../test/playwright/index.js';
-import { AnchorButtonAppearance, AnchorButtonShape, AnchorButtonSize } from './anchor-button.options.js';
+import { AnchorButtonAppearance, AnchorButtonShape, AnchorButtonSize, tagName } from './anchor-button.options.js';
test.describe('Anchor Button', () => {
test.use({
- innerHTML: 'Fluent Anchor Button',
- tagName: 'fluent-anchor-button',
+ innerHTML: 'Anchor Button',
+ tagName,
});
test('should create with document.createElement()', async ({ page, fastPage }) => {
@@ -16,9 +16,9 @@ test.describe('Anchor Button', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-anchor-button');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
diff --git a/packages/web-components/src/avatar/avatar.spec.ts b/packages/web-components/src/avatar/avatar.spec.ts
index 19c236542e9b0b..0556964a2eb83e 100644
--- a/packages/web-components/src/avatar/avatar.spec.ts
+++ b/packages/web-components/src/avatar/avatar.spec.ts
@@ -1,9 +1,9 @@
import { expect, test } from '../../test/playwright/index.js';
-import { AvatarAppearance, AvatarColor, AvatarSize } from './avatar.options.js';
+import { AvatarAppearance, AvatarColor, AvatarSize, tagName } from './avatar.options.js';
test.describe('Avatar', () => {
test.use({
- tagName: 'fluent-avatar',
+ tagName,
});
test('should create with document.createElement()', async ({ page, fastPage }) => {
@@ -15,9 +15,9 @@ test.describe('Avatar', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-avatar');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -25,6 +25,8 @@ test.describe('Avatar', () => {
test('should have a `role` of `img`', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).toHaveJSProperty('elementInternals.role', 'img');
});
@@ -37,13 +39,13 @@ test.describe('Avatar', () => {
await expect(icon).toBeVisible();
await test.step('should NOT render the icon when empty elements are present in the default slot', async () => {
- await fastPage.setTemplate({ innerHTML: `\n\n` });
+ await fastPage.updateTemplate(element, { innerHTML: `\n\n` });
await expect(icon).toBeHidden();
});
await test.step('should retain comment nodes in the default slot when no name or initials are provided', async () => {
- await fastPage.setTemplate({ innerHTML: `\n\n\n` });
+ await fastPage.updateTemplate(element, { innerHTML: `\n\n\n` });
await expect(icon).toBeVisible();
});
@@ -102,7 +104,11 @@ test.describe('Avatar', () => {
});
test('should have a data-color attribute of `neutral` when no color is provided', async ({ fastPage }) => {
- await expect(fastPage.element).toHaveAttribute('data-color', 'neutral');
+ const { element } = fastPage;
+
+ await fastPage.setTemplate();
+
+ await expect(element).toHaveAttribute('data-color', 'neutral');
});
test('should add a data-color attribute of `brand` when `brand is provided as the color', async ({ fastPage }) => {
@@ -124,9 +130,11 @@ test.describe('Avatar', () => {
test('should set the `data-color` attribute to match the `color` attribute', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const color of Object.values(AvatarColor)) {
await test.step(`should set the \`color\` property to \`${color}\``, async () => {
- await fastPage.setTemplate({ attributes: { color } });
+ await fastPage.updateTemplate(element, { attributes: { color } });
await expect(element).toHaveAttribute('color', color);
@@ -143,9 +151,11 @@ test.describe('Avatar', () => {
test('should set the `size` property to match the `size` attribute', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const size of Object.values(AvatarSize)) {
await test.step(`should set the \`size\` property to \`${size}\``, async () => {
- await fastPage.setTemplate({ attributes: { size: `${size}` } });
+ await fastPage.updateTemplate(element, { attributes: { size: `${size}` } });
await expect(element).toHaveAttribute('size', `${size}`);
@@ -157,9 +167,11 @@ test.describe('Avatar', () => {
test('should set the `appearance` property to match the `appearance` attribute', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const appearance of Object.values(AvatarAppearance)) {
await test.step(appearance, async () => {
- await fastPage.setTemplate({ attributes: { appearance } });
+ await fastPage.updateTemplate(element, { attributes: { appearance } });
await expect(element).toHaveJSProperty('appearance', appearance);
diff --git a/packages/web-components/src/badge/badge.spec.ts b/packages/web-components/src/badge/badge.spec.ts
index 4c84a7271f9782..df4ee10a746c44 100644
--- a/packages/web-components/src/badge/badge.spec.ts
+++ b/packages/web-components/src/badge/badge.spec.ts
@@ -1,9 +1,9 @@
import { expect, test } from '../../test/playwright/index.js';
-import { BadgeAppearance, BadgeColor, BadgeShape, BadgeSize } from './badge.options.js';
+import { BadgeAppearance, BadgeColor, BadgeShape, BadgeSize, tagName } from './badge.options.js';
test.describe('Badge', () => {
test.use({
- tagName: 'fluent-badge',
+ tagName,
innerHTML: 'Badge',
});
@@ -16,9 +16,9 @@ test.describe('Badge', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-badge');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
diff --git a/packages/web-components/src/button/button.spec.ts b/packages/web-components/src/button/button.spec.ts
index 77f66a0984cdb1..263a8282786752 100644
--- a/packages/web-components/src/button/button.spec.ts
+++ b/packages/web-components/src/button/button.spec.ts
@@ -1,8 +1,9 @@
import { expect, test } from '../../test/playwright/index.js';
+import { tagName } from './button.options.js';
test.describe('Button', () => {
test.use({
- tagName: 'fluent-button',
+ tagName,
innerHTML: 'Button',
});
@@ -15,9 +16,9 @@ test.describe('Button', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-button');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -27,7 +28,7 @@ test.describe('Button', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -44,7 +45,7 @@ test.describe('Button', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -61,7 +62,7 @@ test.describe('Button', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -75,7 +76,7 @@ test.describe('Button', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -92,7 +93,7 @@ test.describe('Button', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -104,6 +105,8 @@ test.describe('Button', () => {
test('should be focusable by default', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await element.focus();
await expect(element).toBeFocused();
@@ -241,12 +244,13 @@ test.describe('Button', () => {
}
test('should NOT receive focus when the `tabindex` is manually set to -1', async ({ fastPage, page }) => {
- const element = page.locator('fluent-button', { hasText: 'Not Focusable' });
- const focusable = page.locator('fluent-button', { hasText: 'Recieves Focus' });
+ const { element } = fastPage;
+ const focusable = element.nth(0);
+ const notFocusable = element.nth(1);
await fastPage.setTemplate(/* html */ `
- Recieves Focus
- Not Focusable
+ <${tagName}>Recieves Focus${tagName}>
+ <${tagName} tabindex="-1">Not Focusable${tagName}>
`);
await focusable.focus();
@@ -255,7 +259,7 @@ test.describe('Button', () => {
await focusable.press('Tab');
- await expect(element).not.toBeFocused();
+ await expect(notFocusable).not.toBeFocused();
});
test('should focus the element when the `autofocus` attribute is present', async ({ fastPage }) => {
@@ -271,7 +275,7 @@ test.describe('Button', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -290,7 +294,7 @@ test.describe('Button', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -315,7 +319,7 @@ test.describe('Button', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -334,7 +338,7 @@ test.describe('Button', () => {
await fastPage.setTemplate(/* html */ `
- Submit Button
+ <${tagName} type="submit">Submit Button${tagName}>
`);
await element.click();
@@ -354,7 +358,7 @@ test.describe('Button', () => {
Unrelated Form
- Submit Button
+ <${tagName} type="reset">Submit Button${tagName}>
`);
await expect(input).toHaveValue('');
@@ -375,7 +379,7 @@ test.describe('Button', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -395,7 +399,7 @@ test.describe('Button', () => {
- Submit Button
+ <${tagName} type="submit" form="testform">Submit Button${tagName}>
`);
await expect(page).not.toHaveURL(/foo/);
@@ -410,7 +414,7 @@ test.describe('Button', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -431,7 +435,7 @@ test.describe('Button', () => {
- Submit Button
+ <${tagName} type="submit" form="testform" formaction="bar">Submit Button${tagName}>
`);
await element.click();
@@ -446,7 +450,7 @@ test.describe('Button', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -472,7 +476,7 @@ test.describe('Button', () => {
- Submit Button
+ <${tagName} type="submit" form="testform" formmethod="post">Submit Button${tagName}>
`);
await expect(page).not.toHaveURL(/foo/);
@@ -492,7 +496,7 @@ test.describe('Button', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -514,7 +518,7 @@ test.describe('Button', () => {
- Submit Button
+ <${tagName} type="submit" form="testform" formenctype="plain/text">Submit Button${tagName}>
`);
await expect(page).not.toHaveURL(/foo/);
@@ -529,7 +533,7 @@ test.describe('Button', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -551,7 +555,7 @@ test.describe('Button', () => {
- Submit Button
+ <${tagName} type="submit" form="testform" formtarget="_self">Submit Button${tagName}>
`);
await expect(page).not.toHaveURL(/foo/);
@@ -572,7 +576,7 @@ test.describe('Button', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -602,7 +606,7 @@ test.describe('Button', () => {
- Button
+ <${tagName} type="submit" form="test-form" formnovalidate>Button${tagName}>
`);
await input.fill('foo');
@@ -620,13 +624,13 @@ test.describe('Button', () => {
fastPage,
page,
}) => {
- const button = page.locator('fluent-button');
+ const button = page.locator(tagName);
const input = page.locator('#text-input');
await fastPage.setTemplate(/* html */ `
`);
@@ -648,7 +652,7 @@ test.describe('Button', () => {
fastPage,
page,
}) => {
- const button = page.locator('fluent-button');
+ const button = page.locator(tagName);
const input = page.locator('#text-input');
await fastPage.setTemplate(/* html */ `
@@ -656,7 +660,7 @@ test.describe('Button', () => {
- Button
+ <${tagName} type="submit" form="test-form">Button${tagName}>
`);
await input.fill('foo');
diff --git a/packages/web-components/src/checkbox/checkbox.spec.ts b/packages/web-components/src/checkbox/checkbox.spec.ts
index 0abab1d376ac14..26fbbf93209be9 100644
--- a/packages/web-components/src/checkbox/checkbox.spec.ts
+++ b/packages/web-components/src/checkbox/checkbox.spec.ts
@@ -1,11 +1,11 @@
import { expect, test } from '../../test/playwright/index.js';
+
import type { Checkbox } from './checkbox.js';
-import { CheckboxShape, CheckboxSize } from './checkbox.options.js';
+import { CheckboxShape, CheckboxSize, tagName } from './checkbox.options.js';
test.describe('Checkbox', () => {
test.use({
- tagName: 'fluent-checkbox',
- waitFor: ['fluent-button'],
+ tagName,
});
test('should create with document.createElement()', async ({ page, fastPage }) => {
@@ -17,33 +17,37 @@ test.describe('Checkbox', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-checkbox');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
test('should have a role of `checkbox`', async ({ fastPage }) => {
- await expect(fastPage.element).toHaveJSProperty('elementInternals.role', 'checkbox');
+ const { element } = fastPage;
+
+ await fastPage.setTemplate();
+
+ await expect(element).toHaveJSProperty('elementInternals.role', 'checkbox');
});
test('should initialize to the initial value if no value property is set', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).toHaveJSProperty('value', 'on');
});
test('should set the `shape` property to match the `shape` attribute', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const shape of Object.values(CheckboxShape)) {
await test.step(`should set the \`shape\` property to "${shape}"`, async () => {
- await fastPage.setTemplate({
- attributes: {
- shape,
- },
- });
+ await fastPage.updateTemplate(element, { attributes: { shape } });
await expect(element).toHaveAttribute('shape', shape);
@@ -55,9 +59,11 @@ test.describe('Checkbox', () => {
test('should set the `size` property to match the `size` attribute', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const size of Object.values(CheckboxSize)) {
await test.step(`should set the \`size\` property to "${size}"`, async () => {
- await fastPage.setTemplate({ attributes: { size: size } });
+ await fastPage.updateTemplate(element, { attributes: { size } });
await expect(element).toHaveJSProperty('size', size);
@@ -69,6 +75,8 @@ test.describe('Checkbox', () => {
test('should set the `ariaChecked` property equal to the `checked` property', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).toHaveJSProperty('elementInternals.ariaChecked', 'false');
await element.evaluate((node: Checkbox) => {
@@ -81,6 +89,8 @@ test.describe('Checkbox', () => {
test('should NOT set a default `aria-required` value when `required` is not defined', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).not.toHaveAttribute('required');
await expect(element).not.toHaveAttribute('aria-required');
@@ -89,6 +99,8 @@ test.describe('Checkbox', () => {
test('should be focusable by default', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await element.focus();
await expect(element).toBeFocused();
@@ -109,6 +121,8 @@ test.describe('Checkbox', () => {
}) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await element.evaluate((node: Checkbox) => {
node.indeterminate = true;
});
@@ -125,6 +139,8 @@ test.describe('Checkbox', () => {
test('should set `indeterminate` to false when the `checked` state changes via click', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await element.evaluate((node: Checkbox) => {
node.indeterminate = true;
});
@@ -142,7 +158,7 @@ test.describe('Checkbox', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -176,22 +192,26 @@ test.describe('Checkbox', () => {
await fastPage.setTemplate('');
- const value = await page.evaluate(expectedValue => {
- const node = document.createElement('fluent-checkbox') as Checkbox;
+ const value = await page.evaluate(
+ ([expectedValue, tagName]) => {
+ const node = document.createElement(tagName) as Checkbox;
- node.setAttribute('value', expectedValue);
+ node.setAttribute('value', expectedValue);
- return node.value;
- }, expectedValue);
+ return node.value;
+ },
+ [expectedValue, tagName],
+ );
expect(value).toBe(expectedValue);
});
test('should initialize to the provided `value` attribute when set post-connection', async ({ fastPage }) => {
const { element } = fastPage;
-
const expectedValue = 'foobar';
+ await fastPage.setTemplate();
+
await element.evaluate((node: Checkbox, expectedValue) => {
node.setAttribute('value', expectedValue);
}, expectedValue);
@@ -206,13 +226,16 @@ test.describe('Checkbox', () => {
const expectedValue = 'foobar';
- const value = await page.evaluate(expectedValue => {
- const node = document.createElement('fluent-checkbox') as Checkbox;
+ const value = await page.evaluate(
+ ([expectedValue, tagName]) => {
+ const node = document.createElement(tagName) as Checkbox;
- node.value = expectedValue;
+ node.value = expectedValue;
- return node.value;
- }, expectedValue);
+ return node.value;
+ },
+ [expectedValue, tagName],
+ );
expect(value).toBe(expectedValue);
});
@@ -222,7 +245,7 @@ test.describe('Checkbox', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -234,7 +257,7 @@ test.describe('Checkbox', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -251,7 +274,7 @@ test.describe('Checkbox', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -276,7 +299,7 @@ test.describe('Checkbox', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -304,7 +327,7 @@ test.describe('Checkbox', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -334,7 +357,7 @@ test.describe('Checkbox', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -354,8 +377,8 @@ test.describe('Checkbox', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -373,13 +396,13 @@ test.describe('Checkbox', () => {
page,
}) => {
const { element } = fastPage;
- const submitButton = page.locator('fluent-button');
+ const submitButton = page.locator('button[type="submit"]');
await fastPage.setTemplate(/* html */ `
`);
diff --git a/packages/web-components/src/counter-badge/counter-badge.spec.ts b/packages/web-components/src/counter-badge/counter-badge.spec.ts
index ff9cf98cd04b01..fc24a15e25f402 100644
--- a/packages/web-components/src/counter-badge/counter-badge.spec.ts
+++ b/packages/web-components/src/counter-badge/counter-badge.spec.ts
@@ -5,11 +5,12 @@ import {
CounterBadgeColor,
CounterBadgeShape,
CounterBadgeSize,
+ tagName,
} from './counter-badge.options.js';
test.describe('CounterBadge component', () => {
test.use({
- tagName: 'fluent-counter-badge',
+ tagName,
});
test('should create with document.createElement()', async ({ page, fastPage }) => {
@@ -21,9 +22,9 @@ test.describe('CounterBadge component', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-counter-badge');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -174,9 +175,11 @@ test.describe('CounterBadge component', () => {
test('should set the `shape` property to match the `shape` attribute', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const shape of Object.values(CounterBadgeShape)) {
await test.step(`should set the \`shape\` property to \`${shape}\``, async () => {
- await fastPage.setTemplate({ attributes: { shape } });
+ await fastPage.updateTemplate(element, { attributes: { shape } });
await expect(element).toHaveAttribute('shape', shape);
@@ -188,9 +191,11 @@ test.describe('CounterBadge component', () => {
test('should set the `color` property to match the `color` attribute', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const color of Object.values(CounterBadgeColor)) {
await test.step(`should set the \`color\` property to \`${color}\``, async () => {
- await fastPage.setTemplate({ attributes: { color } });
+ await fastPage.updateTemplate(element, { attributes: { color } });
await expect(element).toHaveAttribute('color', color);
@@ -202,9 +207,11 @@ test.describe('CounterBadge component', () => {
test('should set the `size` property to match the `size` attribute', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const size of Object.values(CounterBadgeSize)) {
await test.step(`should set the \`size\` property to "${size}"`, async () => {
- await fastPage.setTemplate({ attributes: { size } });
+ await fastPage.updateTemplate(element, { attributes: { size } });
await expect(element).toHaveAttribute('size', size);
@@ -216,9 +223,11 @@ test.describe('CounterBadge component', () => {
test('should set the `appearance` property to match the `appearance` attribute', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const appearance of Object.values(CounterBadgeAppearance)) {
await test.step(appearance, async () => {
- await fastPage.setTemplate({ attributes: { appearance } });
+ await fastPage.updateTemplate(element, { attributes: { appearance } });
await expect(element).toHaveJSProperty('appearance', appearance);
diff --git a/packages/web-components/src/dialog/dialog.spec.ts b/packages/web-components/src/dialog/dialog.spec.ts
index d5aaf22c9048ef..967a655033e40e 100644
--- a/packages/web-components/src/dialog/dialog.spec.ts
+++ b/packages/web-components/src/dialog/dialog.spec.ts
@@ -1,22 +1,24 @@
import type { Locator } from '@playwright/test';
import { expect, test } from '../../test/playwright/index.js';
+import { tagName as DialogBodyTagName } from '../dialog-body/dialog-body.options.js';
import type { Dialog } from './dialog.js';
+import { tagName } from './dialog.options.js';
test.describe('Dialog', () => {
test.use({
- tagName: 'fluent-dialog',
+ tagName,
innerHTML: /* html */ `Dialog Body
`,
- waitFor: ['fluent-button', 'fluent-dialog-body'],
+ waitFor: [DialogBodyTagName],
});
async function getPointOutside(element: Locator) {
// Get the bounding box of the element
- const boundingBox = (await element.boundingBox()) as { x: number; y: number; width: number; height: number };
+ const boundingBox = await element.boundingBox();
// Calculate a point outside the bounding box
return {
- x: boundingBox.x + boundingBox.width + 10, // 10 pixels to the right
- y: boundingBox.y + boundingBox.height + 10, // 10 pixels below
+ x: boundingBox!.x + boundingBox!.width + 10, // 10 pixels to the right
+ y: boundingBox!.y + boundingBox!.height + 10, // 10 pixels below
};
}
@@ -29,9 +31,9 @@ test.describe('Dialog', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-dialog');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -40,6 +42,8 @@ test.describe('Dialog', () => {
const { element } = fastPage;
const content = element.locator('#content');
+ await fastPage.setTemplate();
+
await test.step('should show the dialog content when the dialog is shown', async () => {
await expect(content).toBeHidden();
@@ -66,6 +70,8 @@ test.describe('Dialog', () => {
const { element } = fastPage;
const content = element.locator('#content');
+ await fastPage.setTemplate();
+
await element.evaluate((node: Dialog) => {
node.show();
});
@@ -116,6 +122,8 @@ test.describe('Dialog', () => {
const { element } = fastPage;
const content = element.locator('#content');
+ await fastPage.setTemplate();
+
await element.evaluate((node: Dialog) => {
node.setAttribute('type', 'alert');
node.show();
@@ -139,6 +147,8 @@ test.describe('Dialog', () => {
const { element } = fastPage;
const content = element.locator('#content');
+ await fastPage.setTemplate();
+
await element.evaluate((node: Dialog) => {
node.show();
});
@@ -152,17 +162,17 @@ test.describe('Dialog', () => {
test('should close after a button is slotted into the close slot and clicked', async ({ fastPage, page }) => {
const { element } = fastPage;
- const closeButton = element.locator('fluent-button[slot="close"]');
+ const closeButton = element.locator('button[slot="close"]');
const content = element.locator('#content');
- await fastPage.setTemplate(/* html */ `
-
-
- Close
- content
-
-
- `);
+ await fastPage.setTemplate({
+ innerHTML: /* html */ `
+ <${DialogBodyTagName}>
+
+ content
+ ${DialogBodyTagName}>
+ `,
+ });
await element.evaluate((node: Dialog) => {
node.show();
@@ -177,17 +187,18 @@ test.describe('Dialog', () => {
test('should NOT close after a slotted button is clicked', async ({ fastPage, page }) => {
const { element } = fastPage;
- const genericButton = element.locator('fluent-button');
+ const genericButton = element.locator('button');
const content = element.locator('#content');
- await fastPage.setTemplate(/* html */ `
-
-
- Close
- content
-
-
- `);
+ await fastPage.setTemplate({
+ attributes: { type: 'non-modal' },
+ innerHTML: /* html */ `
+ <${DialogBodyTagName}>
+
+ content
+ ${DialogBodyTagName}>
+ `,
+ });
await element.evaluate((node: Dialog) => {
node.show();
@@ -292,6 +303,8 @@ test.describe('Dialog', () => {
const { element } = fastPage;
const dialog = element.locator('dialog');
+ await fastPage.setTemplate();
+
await expect(dialog).not.toHaveAttribute('aria-labelledby');
await element.evaluate(node => {
@@ -307,6 +320,8 @@ test.describe('Dialog', () => {
const { element } = fastPage;
const dialog = element.locator('dialog');
+ await fastPage.setTemplate();
+
await expect(dialog).not.toHaveAttribute('aria-describedby');
await element.evaluate(node => {
@@ -322,6 +337,8 @@ test.describe('Dialog', () => {
const { element } = fastPage;
const dialog = element.locator('dialog');
+ await fastPage.setTemplate();
+
await expect(dialog).not.toHaveAttribute('aria-label');
await element.evaluate(node => {
@@ -337,14 +354,14 @@ test.describe('Dialog', () => {
const label = page.locator('label');
const input = page.locator('input');
- await fastPage.setTemplate(/* html */ `
-
-
+ await fastPage.setTemplate({
+ innerHTML: /* html */ `
+ <${DialogBodyTagName} id="content">
-
-
- `);
+ ${DialogBodyTagName}>
+ `,
+ });
await element.evaluate((node: Dialog) => {
node.show();
diff --git a/packages/web-components/src/divider/divider.spec.ts b/packages/web-components/src/divider/divider.spec.ts
index 1683f67aebd357..035c94ad2ddbd9 100644
--- a/packages/web-components/src/divider/divider.spec.ts
+++ b/packages/web-components/src/divider/divider.spec.ts
@@ -1,9 +1,9 @@
import { expect, test } from '../../test/playwright/index.js';
import type { Divider } from './divider.js';
-import { DividerAlignContent, DividerAppearance, DividerOrientation, DividerRole } from './divider.options.js';
+import { DividerAlignContent, DividerAppearance, DividerOrientation, DividerRole, tagName } from './divider.options.js';
test.describe('Divider', () => {
- test.use({ tagName: 'fluent-divider' });
+ test.use({ tagName });
test('should create with document.createElement()', async ({ page, fastPage }) => {
await fastPage.setTemplate();
@@ -14,9 +14,9 @@ test.describe('Divider', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-divider');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -24,15 +24,19 @@ test.describe('Divider', () => {
test('should set a default `role` attribute of "separator"', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).toHaveJSProperty('elementInternals.role', 'separator');
});
test('should set the internal `role` property to match the `role` attribute', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const role of Object.values(DividerRole)) {
await test.step(`role="${role}"`, async () => {
- await fastPage.setTemplate({ attributes: { role } });
+ await fastPage.updateTemplate(element, { attributes: { role } });
await expect(element).toHaveJSProperty('elementInternals.role', role);
});
@@ -42,9 +46,11 @@ test.describe('Divider', () => {
test('should set the `aria-orientation` attribute equal to the `orientation` value', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const orientation of Object.values(DividerOrientation)) {
await test.step(`orientation="${orientation}"`, async () => {
- await fastPage.setTemplate({ attributes: { orientation } });
+ await fastPage.updateTemplate(element, { attributes: { orientation } });
await expect(element).toHaveJSProperty('elementInternals.ariaOrientation', orientation);
});
@@ -83,9 +89,11 @@ test.describe('Divider', () => {
test('should initialize to the provided value attribute if set post-connection', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const alignment of Object.values(DividerAlignContent)) {
await test.step(`alignContent="${alignment}"`, async () => {
- await fastPage.setTemplate({ attributes: { 'align-content': alignment } });
+ await fastPage.updateTemplate(element, { attributes: { 'align-content': alignment } });
await expect(element).toHaveJSProperty('alignContent', alignment);
});
@@ -93,14 +101,14 @@ test.describe('Divider', () => {
for (const appearance of Object.values(DividerAppearance)) {
await test.step(`appearance="${appearance}"`, async () => {
- await fastPage.setTemplate({ attributes: { appearance } });
+ await fastPage.updateTemplate(element, { attributes: { appearance } });
await expect(element).toHaveJSProperty('appearance', appearance);
});
}
await test.step('inset', async () => {
- await fastPage.setTemplate({ attributes: { inset: true } });
+ await fastPage.updateTemplate(element, { attributes: { inset: true } });
await expect(element).toHaveJSProperty('inset', true);
});
diff --git a/packages/web-components/src/drawer/drawer.spec.ts b/packages/web-components/src/drawer/drawer.spec.ts
index 60b00ce2770e6c..159706f678c3a8 100644
--- a/packages/web-components/src/drawer/drawer.spec.ts
+++ b/packages/web-components/src/drawer/drawer.spec.ts
@@ -1,11 +1,12 @@
import { expect, test } from '../../test/playwright/index.js';
-import type { Drawer } from './drawer.js';
-import { DrawerPosition } from './drawer.options.js';
-import { DrawerSize, DrawerType } from './drawer.options.js';
+import { tagName as DrawerBodyTagName } from '../drawer-body/drawer-body.options.js';
+import { Drawer } from './drawer.js';
+import { DrawerPosition, DrawerSize, DrawerType, tagName } from './drawer.options.js';
test.describe('Drawer', () => {
test.use({
- tagName: 'fluent-drawer',
+ tagName,
+ waitFor: [DrawerBodyTagName],
});
for (const type of Object.values(DrawerType)) {
@@ -28,9 +29,9 @@ test.describe('Drawer', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-drawer');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -38,9 +39,11 @@ test.describe('Drawer', () => {
test('should set the `size` property to match the `size` attribute', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const size of Object.values(DrawerSize)) {
await test.step(`should set the \`size\` property to \`${size}\``, async () => {
- await fastPage.setTemplate({ attributes: { size } });
+ await fastPage.updateTemplate(element, { attributes: { size } });
await expect(element).toHaveAttribute('size', size);
@@ -52,9 +55,11 @@ test.describe('Drawer', () => {
test('should set the `position` property to match the `position` attribute', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const position of Object.values(DrawerPosition)) {
await test.step(`should set the \`position\` property to \`${position}\``, async () => {
- await fastPage.setTemplate({ attributes: { position } });
+ await fastPage.updateTemplate(element, { attributes: { position } });
await expect(element).toHaveAttribute('position', position);
@@ -122,6 +127,8 @@ test.describe('Drawer', () => {
test('should emit a `toggle` event when the `show` method is called', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
const wasOpened = element.evaluate(
node => new Promise(resolve => node.addEventListener('toggle', () => resolve(true))),
);
@@ -136,6 +143,8 @@ test.describe('Drawer', () => {
test('should emit a `beforetoggle` event before open property changes', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
const wasOpened = element.evaluate(
node => new Promise(resolve => node.addEventListener('beforetoggle', () => resolve(true))),
);
@@ -150,6 +159,8 @@ test.describe('Drawer', () => {
test('should emit a `cancel` event when a `cancel` event is invoked on the document', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await element.evaluate((node: Drawer) => {
node.show();
});
@@ -167,17 +178,17 @@ test.describe('Drawer', () => {
test('should close after a button is slotted into the close slot and clicked', async ({ fastPage, page }) => {
const { element } = fastPage;
- const closeButton = element.locator('fluent-button[slot="close"]');
+ const closeButton = element.locator('button[slot="close"]');
const content = element.locator('#content');
- await fastPage.setTemplate(/* html */ `
-
-
- Close
- content
-
-
- `);
+ await fastPage.setTemplate({
+ innerHTML: /* html */ `
+ <${DrawerBodyTagName}>
+
+ content
+ ${DrawerBodyTagName}>
+ `,
+ });
await element.evaluate((node: Drawer) => {
node.show();
diff --git a/packages/web-components/src/dropdown/dropdown.spec.ts b/packages/web-components/src/dropdown/dropdown.spec.ts
index dca5c0a00159ce..cfc2ecec632fb6 100644
--- a/packages/web-components/src/dropdown/dropdown.spec.ts
+++ b/packages/web-components/src/dropdown/dropdown.spec.ts
@@ -1,22 +1,25 @@
import { expect, test } from '../../test/playwright/index.js';
+import { tagName as ListboxTagName } from '../listbox/listbox.options.js';
+import { tagName as OptionTagName } from '../option/option.options.js';
import type { Dropdown } from './dropdown.js';
+import { tagName } from './dropdown.options.js';
test.describe('Dropdown', () => {
test.use({
- tagName: 'fluent-dropdown',
+ tagName,
innerHTML: /* html */ `
-
- Apple
- Banana
- Orange
- Mango
- Kiwi
- Cherry
- Grapefruit
- Papaya
-
+ <${ListboxTagName}>
+ <${OptionTagName} value="apple">Apple${OptionTagName}>
+ <${OptionTagName} value="banana">Banana${OptionTagName}>
+ <${OptionTagName} value="orange">Orange${OptionTagName}>
+ <${OptionTagName} value="mango">Mango${OptionTagName}>
+ <${OptionTagName} value="kiwi">Kiwi${OptionTagName}>
+ <${OptionTagName} value="cherry">Cherry${OptionTagName}>
+ <${OptionTagName} value="grapefruit">Grapefruit${OptionTagName}>
+ <${OptionTagName} value="papaya">Papaya${OptionTagName}>
+ ${ListboxTagName}>
`,
- waitFor: ['fluent-listbox', 'fluent-option'],
+ waitFor: [ListboxTagName, OptionTagName],
});
test('should create with document.createElement()', async ({ page, fastPage }) => {
@@ -28,9 +31,9 @@ test.describe('Dropdown', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-dropdown');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -38,12 +41,16 @@ test.describe('Dropdown', () => {
test('should render a dropdown', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).toHaveCount(1);
});
test('should render a dropdown with options', async ({ fastPage }) => {
const { element } = fastPage;
- const options = element.locator('fluent-option');
+ const options = element.locator(OptionTagName);
+
+ await fastPage.setTemplate();
await expect(options).toHaveCount(8);
});
@@ -52,6 +59,8 @@ test.describe('Dropdown', () => {
const { element } = fastPage;
const button = element.locator('button');
+ await fastPage.setTemplate();
+
await expect(button).toHaveCount(1);
});
@@ -66,7 +75,9 @@ test.describe('Dropdown', () => {
test('should open the dropdown on click', async ({ fastPage }) => {
const { element } = fastPage;
- const listbox = element.locator('fluent-listbox');
+ const listbox = element.locator(ListboxTagName);
+
+ await fastPage.setTemplate();
await expect(listbox).toBeHidden();
@@ -77,9 +88,11 @@ test.describe('Dropdown', () => {
test('should close the dropdown on click', async ({ fastPage }) => {
const { element } = fastPage;
- const listbox = element.locator('fluent-listbox');
+ const listbox = element.locator(ListboxTagName);
const button = element.locator('[role=combobox]');
+ await fastPage.setTemplate();
+
await button.click();
await expect(listbox).toBeVisible();
@@ -91,9 +104,11 @@ test.describe('Dropdown', () => {
test('should open the dropdown when the space key is pressed', async ({ fastPage }) => {
const { element } = fastPage;
- const listbox = element.locator('fluent-listbox');
+ const listbox = element.locator(ListboxTagName);
const button = element.locator('[role=combobox]');
+ await fastPage.setTemplate();
+
await button.press(' ');
await expect(listbox).toBeVisible();
@@ -101,7 +116,7 @@ test.describe('Dropdown', () => {
test("should set the `name` property on options when it's set on the dropdown", async ({ fastPage }) => {
const { element } = fastPage;
- const options = element.locator('fluent-option');
+ const options = element.locator(OptionTagName);
await fastPage.setTemplate({ attributes: { name: 'fruit' } });
@@ -117,29 +132,29 @@ test.describe('Dropdown', () => {
await fastPage.setTemplate(/* html */ `
`);
await element.click();
- await expect(element.locator('fluent-listbox')).toBeVisible();
+ await expect(element.locator(ListboxTagName)).toBeVisible();
- await element.locator('fluent-option[value=cherry]').click();
+ await element.locator(`${OptionTagName}[value=cherry]`).click();
- await expect(element.locator('fluent-option[value=cherry]')).toHaveJSProperty('selected', true);
+ await expect(element.locator(`${OptionTagName}[value=cherry]`)).toHaveJSProperty('selected', true);
await submitButton.click();
@@ -152,25 +167,25 @@ test.describe('Dropdown', () => {
await fastPage.setTemplate(/* html */ `
`);
await element.click();
- await expect(element.locator('fluent-listbox')).toBeHidden();
+ await expect(element.locator(ListboxTagName)).toBeHidden();
await submitButton.click();
@@ -186,25 +201,25 @@ test.describe('Dropdown', () => {
await fastPage.setTemplate(/* html */ `
`);
await element.click();
- await expect(element.locator('fluent-listbox')).toBeVisible();
+ await expect(element.locator(ListboxTagName)).toBeVisible();
await submitButton.click();
@@ -222,27 +237,27 @@ test.describe('Dropdown', () => {
await fastPage.setTemplate(/* html */ `
`);
- await expect(element.locator('fluent-option[value=mango]')).toHaveJSProperty('selected', true);
- await expect(element.locator('fluent-option[value=mango]')).toHaveAttribute('selected');
+ await expect(element.locator(`${OptionTagName}[value=mango]`)).toHaveJSProperty('selected', true);
+ await expect(element.locator(`${OptionTagName}[value=mango]`)).toHaveAttribute('selected');
- await expect(element.locator('fluent-option[value=kiwi]')).toHaveJSProperty('selected', true);
- await expect(element.locator('fluent-option[value=kiwi]')).toHaveAttribute('selected');
+ await expect(element.locator(`${OptionTagName}[value=kiwi]`)).toHaveJSProperty('selected', true);
+ await expect(element.locator(`${OptionTagName}[value=kiwi]`)).toHaveAttribute('selected');
await submitButton.click();
@@ -257,37 +272,37 @@ test.describe('Dropdown', () => {
await fastPage.setTemplate(/* html */ `
`);
await element.click();
- await expect(element.locator('fluent-listbox')).toBeVisible();
+ await expect(element.locator(ListboxTagName)).toBeVisible();
- await element.locator('fluent-option[value=kiwi]').click();
+ await element.locator(`${OptionTagName}[value=kiwi]`).click();
- await expect(element.locator('fluent-option[value=kiwi]')).toHaveJSProperty('selected', true);
+ await expect(element.locator(`${OptionTagName}[value=kiwi]`)).toHaveJSProperty('selected', true);
- await expect(element.locator('fluent-option[value=mango]')).toHaveJSProperty('selected', false);
+ await expect(element.locator(`${OptionTagName}[value=mango]`)).toHaveJSProperty('selected', false);
await resetButton.click();
- await expect(element.locator('fluent-option[value=mango]')).toHaveJSProperty('selected', true);
+ await expect(element.locator(`${OptionTagName}[value=mango]`)).toHaveJSProperty('selected', true);
- await expect(element.locator('fluent-option[value=kiwi]')).toHaveJSProperty('selected', false);
+ await expect(element.locator(`${OptionTagName}[value=kiwi]`)).toHaveJSProperty('selected', false);
});
test('should reset the values when the form is reset and the `multiple` attribute is present', async ({
@@ -299,41 +314,41 @@ test.describe('Dropdown', () => {
await fastPage.setTemplate(/* html */ `
`);
await element.click();
- await expect(element.locator('fluent-listbox')).toBeVisible();
+ await expect(element.locator(ListboxTagName)).toBeVisible();
- await element.locator('fluent-option[value=apple]').click();
+ await element.locator(`${OptionTagName}[value=apple]`).click();
- await expect(element.locator('fluent-option[value=kiwi]')).toHaveJSProperty('selected', true);
+ await expect(element.locator(`${OptionTagName}[value=kiwi]`)).toHaveJSProperty('selected', true);
- await expect(element.locator('fluent-option[value=mango]')).toHaveJSProperty('selected', true);
+ await expect(element.locator(`${OptionTagName}[value=mango]`)).toHaveJSProperty('selected', true);
- await expect(element.locator('fluent-option[value=apple]')).toHaveJSProperty('selected', true);
+ await expect(element.locator(`${OptionTagName}[value=apple]`)).toHaveJSProperty('selected', true);
await resetButton.click();
- await expect(element.locator('fluent-option[value=mango]')).toHaveJSProperty('selected', true);
+ await expect(element.locator(`${OptionTagName}[value=mango]`)).toHaveJSProperty('selected', true);
- await expect(element.locator('fluent-option[value=kiwi]')).toHaveJSProperty('selected', true);
+ await expect(element.locator(`${OptionTagName}[value=kiwi]`)).toHaveJSProperty('selected', true);
- await expect(element.locator('fluent-option[value=apple]')).toHaveJSProperty('selected', false);
+ await expect(element.locator(`${OptionTagName}[value=apple]`)).toHaveJSProperty('selected', false);
});
test('should display a validation message when the dropdown is required and the form is submitted without a value', async ({
@@ -342,7 +357,7 @@ test.describe('Dropdown', () => {
browserName,
}) => {
const { element } = fastPage;
- const options = element.locator('fluent-option');
+ const options = element.locator(OptionTagName);
const submitButton = page.locator('button[type=submit]');
const messages: Record = {
@@ -354,18 +369,18 @@ test.describe('Dropdown', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -386,8 +401,8 @@ test.describe('Dropdown', () => {
test('should select an option when the user types the value', async ({ fastPage }) => {
const { element } = fastPage;
const input = element.locator('input');
- const listbox = element.locator('fluent-listbox');
- const kiwiOption = element.locator('fluent-option[value=kiwi]');
+ const listbox = element.locator(ListboxTagName);
+ const kiwiOption = element.locator(`${OptionTagName}[value=kiwi]`);
await fastPage.setTemplate({ attributes: { type: 'combobox' } });
@@ -414,7 +429,7 @@ test.describe('Dropdown', () => {
}) => {
const { element } = fastPage;
const input = element.locator('input');
- const listbox = element.locator('fluent-listbox');
+ const listbox = element.locator(ListboxTagName);
await fastPage.setTemplate({ attributes: { type: 'combobox' } });
@@ -441,7 +456,9 @@ test.describe('Dropdown', () => {
page,
}) => {
const { element } = fastPage;
- const listbox = element.locator('fluent-listbox');
+ const listbox = element.locator(ListboxTagName);
+
+ await fastPage.setTemplate();
await element.click();
@@ -464,7 +481,9 @@ test.describe('Dropdown', () => {
test('should emit a `change` event when the value is confirmed by pressing Enter', async ({ fastPage }) => {
const { element } = fastPage;
- const listbox = element.locator('fluent-listbox');
+ const listbox = element.locator(ListboxTagName);
+
+ await fastPage.setTemplate();
await element.click();
@@ -502,6 +521,8 @@ test.describe('Dropdown', () => {
test('should NOT emit a `change` event when the value is changed programmatically', async ({ fastPage, page }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await element.evaluate((el: Dropdown) => {
el.addEventListener('change', () => el.insertAdjacentText('afterend', 'changed'), { once: true });
});
@@ -514,13 +535,15 @@ test.describe('Dropdown', () => {
await expect(element).toHaveJSProperty('value', 'kiwi');
- await expect(element.locator('fluent-option[value=kiwi]')).toHaveJSProperty('selected', true);
+ await expect(element.locator(`${OptionTagName}[value=kiwi]`)).toHaveJSProperty('selected', true);
});
test('should not focus listbox when tabbing from dropdown', async ({ fastPage, page }) => {
const { element } = fastPage;
- const listbox = element.locator('fluent-listbox');
+ await fastPage.setTemplate();
+
+ const listbox = element.locator(ListboxTagName);
await element.focus();
await page.keyboard.press('Tab');
diff --git a/packages/web-components/src/field/field.spec.ts b/packages/web-components/src/field/field.spec.ts
index fa7a2cff709a72..68edb224a408d5 100644
--- a/packages/web-components/src/field/field.spec.ts
+++ b/packages/web-components/src/field/field.spec.ts
@@ -1,11 +1,13 @@
import { expect, test } from '../../test/playwright/index.js';
import type { TextInput } from '../text-input/text-input.js';
+import { tagName as TextInputTagName } from '../text-input/text-input.options.js';
import type { Field } from './field.js';
+import { tagName } from './field.options.js';
test.describe('Field', () => {
test.use({
- tagName: 'fluent-field',
- waitFor: ['fluent-text-input'],
+ tagName,
+ waitFor: [TextInputTagName],
});
test('should create with document.createElement()', async ({ page, fastPage }) => {
@@ -17,9 +19,9 @@ test.describe('Field', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-field');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -388,7 +390,7 @@ test.describe('Field', () => {
await fastPage.setTemplate({
innerHTML: /* html */ `
-
+ <${TextInputTagName} id="input" slot="input" type="text">${TextInputTagName}>
I have no idea how you managed to do this.
`,
});
diff --git a/packages/web-components/src/image/image.spec.ts b/packages/web-components/src/image/image.spec.ts
index 19c5e6c068e3bd..0db5aeda36711b 100644
--- a/packages/web-components/src/image/image.spec.ts
+++ b/packages/web-components/src/image/image.spec.ts
@@ -1,10 +1,10 @@
import { expect, test } from '../../test/playwright/index.js';
import type { Image } from './image.js';
-import { ImageFit, ImageShape } from './image.options.js';
+import { ImageFit, ImageShape, tagName } from './image.options.js';
test.describe('Image', () => {
test.use({
- tagName: 'fluent-image',
+ tagName,
innerHTML: /* html */ `
`,
@@ -19,9 +19,9 @@ test.describe('Image', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-image');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -83,9 +83,11 @@ test.describe('Image', () => {
test('should set the `fit` property to match the `fit` attribute', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const fit of Object.values(ImageFit)) {
await test.step(`should set the \`fit\` property to "${fit}"`, async () => {
- await fastPage.setTemplate({ attributes: { fit } });
+ await fastPage.updateTemplate(element, { attributes: { fit } });
await expect(element).toHaveAttribute('fit', fit);
@@ -97,9 +99,11 @@ test.describe('Image', () => {
test('should set the `shape` property to match the `shape` attribute', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const shape of Object.values(ImageShape)) {
await test.step(`should set the \`shape\` property to "${shape}"`, async () => {
- await fastPage.setTemplate({ attributes: { shape } });
+ await fastPage.updateTemplate(element, { attributes: { shape } });
await expect(element).toHaveAttribute('shape', shape);
diff --git a/packages/web-components/src/label/label.spec.ts b/packages/web-components/src/label/label.spec.ts
index 2dff43462aed66..56f17a8f56bfba 100644
--- a/packages/web-components/src/label/label.spec.ts
+++ b/packages/web-components/src/label/label.spec.ts
@@ -1,16 +1,21 @@
import { expect, test } from '../../test/playwright/index.js';
import type { Label } from './label.js';
-import { LabelSize, LabelWeight } from './label.options.js';
+import { LabelSize, LabelWeight, tagName } from './label.options.js';
test.describe('Label', () => {
- test.use({ tagName: 'fluent-label' });
+ test.use({
+ tagName,
+ innerHTML: 'Label',
+ });
test('should set the `size` property to match the `size` attribute', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const size of Object.values(LabelSize)) {
await test.step(`should set the \`size\` property to "${size}"`, async () => {
- await fastPage.setTemplate({ attributes: { size } });
+ await fastPage.updateTemplate(element, { attributes: { size } });
await expect(element).toHaveAttribute('size', size);
@@ -28,9 +33,9 @@ test.describe('Label', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-label');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -38,9 +43,11 @@ test.describe('Label', () => {
test('should set the `weight` property to match the `weight` attribute', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const weight of Object.values(LabelWeight)) {
await test.step(`should set the \`weight\` property to "${weight}"`, async () => {
- await fastPage.setTemplate({ attributes: { weight } });
+ await fastPage.updateTemplate(element, { attributes: { weight } });
await expect(element).toHaveAttribute('weight', weight);
diff --git a/packages/web-components/src/link/link.spec.ts b/packages/web-components/src/link/link.spec.ts
index aa6d26f2a2cd1e..877c8df6637021 100644
--- a/packages/web-components/src/link/link.spec.ts
+++ b/packages/web-components/src/link/link.spec.ts
@@ -1,6 +1,6 @@
import { expect, test } from '../../test/playwright/index.js';
-import type { Link } from './link.js';
-import { LinkAppearance } from './link.options.js';
+import { Link } from './link.js';
+import { LinkAppearance, tagName } from './link.options.js';
const attributes = {
download: 'download',
@@ -14,7 +14,9 @@ const attributes = {
};
test.describe('Link', () => {
- test.use({ tagName: 'fluent-link' });
+ test.use({
+ tagName,
+ });
test('should create with document.createElement()', async ({ page, fastPage }) => {
await fastPage.setTemplate();
@@ -25,9 +27,9 @@ test.describe('Link', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-link');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -36,9 +38,11 @@ test.describe('Link', () => {
const { element } = fastPage;
const anchor = element.locator('a');
+ await fastPage.setTemplate();
+
for (const [attribute, value] of Object.entries(attributes)) {
await test.step(`should set the \`${attribute}\` property to match the \`${attribute}\` attribute`, async () => {
- await fastPage.setTemplate({ attributes: { [attribute]: value } });
+ await fastPage.updateTemplate(element, { attributes: { [attribute]: value } });
await expect(element).toHaveAttribute(attribute, value);
@@ -54,9 +58,11 @@ test.describe('Link', () => {
test('should set the `appearance` property to match the `appearance` attribute', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const appearance of Object.values(LinkAppearance)) {
await test.step(appearance, async () => {
- await fastPage.setTemplate({ attributes: { appearance } });
+ await fastPage.updateTemplate(element, { attributes: { appearance } });
await expect(element).toHaveJSProperty('appearance', appearance);
@@ -68,6 +74,8 @@ test.describe('Link', () => {
test('should add an "inline" attribute when the `inline` property is true', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await element.evaluate((node: Link) => {
node.inline = true;
});
diff --git a/packages/web-components/src/listbox/listbox.spec.ts b/packages/web-components/src/listbox/listbox.spec.ts
index 402f6282e8194d..ad4d49a7271e58 100644
--- a/packages/web-components/src/listbox/listbox.spec.ts
+++ b/packages/web-components/src/listbox/listbox.spec.ts
@@ -1,20 +1,22 @@
import { expect, test } from '../../test/playwright/index.js';
+import { tagName as OptionTagName } from '../option/option.options.js';
import type { Listbox } from './listbox.js';
+import { tagName } from './listbox.options.js';
test.describe('Listbox', () => {
test.use({
- tagName: 'fluent-listbox',
+ tagName,
innerHTML: /* html */ `
- Apple
- Banana
- Orange
- Mango
- Kiwi
- Cherry
- Grapefruit
- Papaya
+ <${OptionTagName} value="apple">Apple${OptionTagName}>
+ <${OptionTagName} value="banana">Banana${OptionTagName}>
+ <${OptionTagName} value="orange">Orange${OptionTagName}>
+ <${OptionTagName} value="mango">Mango${OptionTagName}>
+ <${OptionTagName} value="kiwi">Kiwi${OptionTagName}>
+ <${OptionTagName} value="cherry">Cherry${OptionTagName}>
+ <${OptionTagName} value="grapefruit">Grapefruit${OptionTagName}>
+ <${OptionTagName} value="papaya">Papaya${OptionTagName}>
`,
- waitFor: ['fluent-option'],
+ waitFor: [OptionTagName],
});
test('should create with document.createElement()', async ({ page, fastPage }) => {
@@ -26,9 +28,9 @@ test.describe('Listbox', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-listbox');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -75,7 +77,7 @@ test.describe('Listbox', () => {
fastPage,
}) => {
const { element } = fastPage;
- const options = element.locator('fluent-option');
+ const options = element.locator(OptionTagName);
await fastPage.setTemplate();
@@ -98,7 +100,7 @@ test.describe('Listbox', () => {
test('should set the `ariaPosInSet` and `ariaSetSize` properties on the options', async ({ fastPage }) => {
const { element } = fastPage;
- const options = element.locator('fluent-option');
+ const options = element.locator(OptionTagName);
await fastPage.setTemplate();
@@ -113,8 +115,8 @@ test.describe('Listbox', () => {
}
await test.step('should update the `ariaPosInSet` and `ariaSetSize` properties when the options change', async () => {
- await element.evaluate((node: Listbox) => {
- const newOption = document.createElement('fluent-option');
+ await element.evaluate((node: Listbox, OptionTagName) => {
+ const newOption = document.createElement(OptionTagName);
newOption.textContent = 'New Option';
node.appendChild(newOption);
@@ -122,7 +124,7 @@ test.describe('Listbox', () => {
for (let i = node.children.length; i >= 0; i--) {
node.appendChild(node.children[(Math.random() * i) | 0]);
}
- });
+ }, OptionTagName);
const newOptionsCount = await options.count();
diff --git a/packages/web-components/src/menu-list/menu-list.spec.ts b/packages/web-components/src/menu-list/menu-list.spec.ts
index be9d7281371c3d..25372a141be4b9 100644
--- a/packages/web-components/src/menu-list/menu-list.spec.ts
+++ b/packages/web-components/src/menu-list/menu-list.spec.ts
@@ -1,16 +1,18 @@
import { expect, test } from '../../test/playwright/index.js';
+import { tagName as DividerTagName } from '../divider/divider.options.js';
import type { MenuItem } from '../menu-item/menu-item.js';
-import { MenuItemRole } from '../menu-item/menu-item.options.js';
+import { MenuItemRole, tagName as MenuItemTagName } from '../menu-item/menu-item.options.js';
+import { tagName } from './menu-list.options.js';
test.describe('MenuList', () => {
test.use({
- tagName: 'fluent-menu-list',
- waitFor: ['fluent-menu-item'],
+ tagName,
+ waitFor: [MenuItemTagName, DividerTagName],
innerHTML: /* html */ `
- Menu item 1
- Menu item 2
- Menu item 3
- Menu item 4
+ <${MenuItemTagName}>Menu item 1${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 2${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 3${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 4${MenuItemTagName}>
`,
});
@@ -23,9 +25,9 @@ test.describe('MenuList', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-menu-list');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -33,34 +35,39 @@ test.describe('MenuList', () => {
test('should have a role of `menu`', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).toHaveJSProperty('elementInternals.role', 'menu');
});
test('should set `tabindex` of the first focusable menu item to 0', async ({ fastPage }) => {
const { element } = fastPage;
- const menuItems = element.locator('fluent-menu-item');
+ const menuItems = element.locator(MenuItemTagName);
+
+ await fastPage.setTemplate();
await expect(menuItems.first()).toHaveAttribute('tabindex', '0');
});
test('should NOT set any `tabindex` on non-menu-item elements', async ({ fastPage }) => {
const { element } = fastPage;
+ const divider = element.locator('div.divider');
await fastPage.setTemplate({
innerHTML: /* html */ `
- Menu item
+ <${MenuItemTagName}>Menu item${MenuItemTagName}>
Not a menu item
`,
});
- const divider = element.locator('div.divider');
-
await expect(divider).not.toHaveAttribute('tabindex');
});
test('should focus on first menu item when `focus()` is called', async ({ fastPage }) => {
const { element } = fastPage;
- const firstItem = element.locator('fluent-menu-item').first();
+ const firstItem = element.locator(MenuItemTagName).first();
+
+ await fastPage.setTemplate();
await expect(firstItem).toHaveAttribute('tabindex', '0');
@@ -88,30 +95,29 @@ test.describe('MenuList', () => {
await fastPage.setTemplate('');
- await page.evaluate(() => {
- const menu = document.createElement('fluent-menu-list');
+ await page.evaluate(tagName => {
+ const menu = document.createElement(tagName);
menu.focus();
document.body.append(menu);
- });
+ }, tagName);
await expect(element).not.toBeFocused();
});
test('should focus disabled items', async ({ fastPage }) => {
const { element } = fastPage;
- const menuItems = element.locator('fluent-menu-item');
+ const menuItems = element.locator(MenuItemTagName);
+ const firstMenuItem = menuItems.first();
await fastPage.setTemplate({
innerHTML: /* html */ `
- Menu item
- Menu item
+ <${MenuItemTagName} disabled>Menu item${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item${MenuItemTagName}>
`,
});
- const firstMenuItem = menuItems.first();
-
await expect(firstMenuItem).toHaveAttribute('disabled');
await expect(firstMenuItem).toHaveJSProperty('elementInternals.ariaDisabled', 'true');
@@ -134,16 +140,9 @@ test.describe('MenuList', () => {
test('should not navigate to hidden items when changed after connection', async ({ fastPage }) => {
const { element } = fastPage;
- const menuItems = element.locator('fluent-menu-item');
+ const menuItems = element.locator(MenuItemTagName);
- await fastPage.setTemplate({
- innerHTML: /* html */ `
- Menu item 1
- Menu item 2
- Menu item 3
- Menu item 4
- `,
- });
+ await fastPage.setTemplate();
await expect(menuItems).toHaveCount(4);
@@ -190,14 +189,14 @@ test.describe('MenuList', () => {
test('should treat all checkbox menu items as individually selectable items', async ({ fastPage }) => {
const { element } = fastPage;
- const menuItems = element.locator('fluent-menu-item');
+ const menuItems = element.locator(MenuItemTagName);
await fastPage.setTemplate({
innerHTML: /* html */ `
- Menu item 1
- Menu item 2
- Menu item 3
- Menu item 4
+ <${MenuItemTagName} role="menuitemcheckbox">Menu item 1${MenuItemTagName}>
+ <${MenuItemTagName} role="menuitemcheckbox">Menu item 2${MenuItemTagName}>
+ <${MenuItemTagName} role="menuitemcheckbox">Menu item 3${MenuItemTagName}>
+ <${MenuItemTagName} role="menuitemcheckbox">Menu item 4${MenuItemTagName}>
`,
});
@@ -218,13 +217,13 @@ test.describe('MenuList', () => {
fastPage,
}) => {
const { element } = fastPage;
- const menuItems = element.locator('fluent-menu-item');
+ const menuItems = element.locator(MenuItemTagName);
await fastPage.setTemplate({
innerHTML: /* html */ `
- Menu item 1
- Menu item 2
- Menu item 3
+ <${MenuItemTagName} role="menuitemradio">Menu item 1${MenuItemTagName}>
+ <${MenuItemTagName} role="menuitemradio">Menu item 2${MenuItemTagName}>
+ <${MenuItemTagName} role="menuitemradio">Menu item 3${MenuItemTagName}>
`,
});
@@ -257,15 +256,15 @@ test.describe('MenuList', () => {
fastPage,
}) => {
const { element } = fastPage;
- const menuItems = element.locator('fluent-menu-item');
+ const menuItems = element.locator(MenuItemTagName);
await fastPage.setTemplate({
innerHTML: /* html */ `
- Menu item 1
- Menu item 2
-
- Menu item 3
- Menu item 4
+ <${MenuItemTagName} role="menuitemradio">Menu item 1${MenuItemTagName}>
+ <${MenuItemTagName} role="menuitemradio">Menu item 2${MenuItemTagName}>
+ <${DividerTagName} role="separator">${DividerTagName}>
+ <${MenuItemTagName} role="menuitemradio">Menu item 3${MenuItemTagName}>
+ <${MenuItemTagName} role="menuitemradio">Menu item 4${MenuItemTagName}>
`,
});
@@ -308,7 +307,9 @@ test.describe('MenuList', () => {
test('should navigate the menu on arrow up/down keys', async ({ fastPage }) => {
const { element } = fastPage;
- const menuItems = element.locator('fluent-menu-item');
+ const menuItems = element.locator(MenuItemTagName);
+
+ await fastPage.setTemplate();
await element.evaluate(node => {
node.focus();
@@ -335,18 +336,18 @@ test.describe('MenuList', () => {
fastPage,
}) => {
const { element } = fastPage;
- const menuItems = element.locator('fluent-menu-item');
+ const menuItems = element.locator(MenuItemTagName);
await fastPage.setTemplate({
innerHTML: /* html */ `
- Menu item 1
-
- Menu item 1.1
- Menu item 1.2
- Menu item 1.3
-
-
+ <${tagName} slot="submenu">
+ <${MenuItemTagName}>Menu item 1.1${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 1.2${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 1.3${MenuItemTagName}>
+ ${tagName}>
+ ${MenuItemTagName}>
`,
});
@@ -365,14 +366,14 @@ test.describe('MenuList', () => {
test('should not navigate to hidden items when set before connection', async ({ fastPage }) => {
const { element } = fastPage;
- const menuItems = element.locator('fluent-menu-item');
+ const menuItems = element.locator(MenuItemTagName);
await fastPage.setTemplate({
innerHTML: /* html */ `
- Menu item 1
- Menu item 2
- Menu item 3
- Menu item 4
+ <${MenuItemTagName}>Menu item 1${MenuItemTagName}>
+ <${MenuItemTagName} hidden="hidden">Menu item 2${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 3${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 4${MenuItemTagName}>
`,
});
@@ -403,7 +404,9 @@ test.describe('MenuList', () => {
fastPage,
}) => {
const { element } = fastPage;
- const menuItems = element.locator('fluent-menu-item');
+ const menuItems = element.locator(MenuItemTagName);
+
+ await fastPage.setTemplate();
for (const item of await menuItems.all()) {
await expect(item).toHaveAttribute('data-indent', '0');
@@ -414,14 +417,14 @@ test.describe('MenuList', () => {
fastPage,
}) => {
const { element } = fastPage;
- const menuItems = element.locator('fluent-menu-item');
+ const menuItems = element.locator(MenuItemTagName);
await fastPage.setTemplate({
innerHTML: /* html */ `
-
- Menu item 2
- Menu item 3
- Menu item 4
+ <${MenuItemTagName} role="menuitemcheckbox">${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 2${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 3${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 4${MenuItemTagName}>
`,
});
@@ -434,14 +437,14 @@ test.describe('MenuList', () => {
fastPage,
}) => {
const { element } = fastPage;
- const menuItems = element.locator('fluent-menu-item');
+ const menuItems = element.locator(MenuItemTagName);
await fastPage.setTemplate({
innerHTML: /* html */ `
-
- Menu item 2
- Menu item 3
- Menu item 4
+ <${MenuItemTagName} role="menuitemradio">${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 2${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 3${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 4${MenuItemTagName}>
`,
});
@@ -454,17 +457,17 @@ test.describe('MenuList', () => {
fastPage,
}) => {
const { element } = fastPage;
- const menuItems = element.locator('fluent-menu-item');
+ const menuItems = element.locator(MenuItemTagName);
await fastPage.setTemplate({
innerHTML: /* html */ `
-
+ <${MenuItemTagName} role="menuitemcheckbox">
Item 1
Icon
-
- Menu item 2
- Menu item 3
- Menu item 4
+ ${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 2${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 3${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 4${MenuItemTagName}>
`,
});
@@ -477,14 +480,14 @@ test.describe('MenuList', () => {
fastPage,
}) => {
const { element } = fastPage;
- const menuItems = element.locator('fluent-menu-item');
+ const menuItems = element.locator(MenuItemTagName);
await fastPage.setTemplate({
innerHTML: /* html */ `
- Item 1 Icon
- Menu item 2
- Menu item 3
- Menu item 4
+ <${MenuItemTagName} role="menuitemradio"> Item 1 Icon ${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 2${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 3${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 4${MenuItemTagName}>
`,
});
@@ -497,21 +500,21 @@ test.describe('MenuList', () => {
fastPage,
}) => {
const { element } = fastPage;
+ const menuItems = element.locator(MenuItemTagName);
await fastPage.setTemplate({ innerHTML: '' });
- await element.evaluate(node => {
+ await element.evaluate((node, MenuItemTagName) => {
const items = ['item 1', 'item 2', 'item 3'];
items.forEach(item => {
- const menuItem = document.createElement('fluent-menu-item');
+ const menuItem = document.createElement(MenuItemTagName);
menuItem.role = 'menuitemradio';
menuItem.textContent = item;
node.append(menuItem);
});
- });
+ }, MenuItemTagName);
- const menuItems = element.locator('fluent-menu-item');
await expect(menuItems).toHaveCount(3);
for (const item of await menuItems.all()) {
@@ -523,24 +526,24 @@ test.describe('MenuList', () => {
fastPage,
}) => {
const { element } = fastPage;
+ const menuItems = element.locator(MenuItemTagName);
await fastPage.setTemplate({ innerHTML: '' });
- await element.evaluate(node => {
+ await element.evaluate((node, MenuItemTagName) => {
const fragment = document.createDocumentFragment();
const items = ['item 1', 'item 2', 'item 3'];
items.forEach(item => {
- const menuItem = document.createElement('fluent-menu-item');
+ const menuItem = document.createElement(MenuItemTagName);
menuItem.role = 'menuitemradio';
menuItem.textContent = item;
fragment.append(menuItem);
});
node.append(fragment);
- });
+ }, MenuItemTagName);
- const menuItems = element.locator('fluent-menu-item');
await expect(menuItems).toHaveCount(3);
for (const item of await menuItems.all()) {
@@ -552,7 +555,9 @@ test.describe('MenuList', () => {
fastPage,
}) => {
const { element } = fastPage;
- const menuItems = element.locator('fluent-menu-item');
+ const menuItems = element.locator(MenuItemTagName);
+
+ await fastPage.setTemplate();
await test.step('all plain menuitems should start with data-indent 0', async () => {
for (const item of await menuItems.all()) {
@@ -561,12 +566,12 @@ test.describe('MenuList', () => {
});
await test.step('appending a menuitemradio should update all items to data-indent 1', async () => {
- await element.evaluate(node => {
- const menuItem = document.createElement('fluent-menu-item');
+ await element.evaluate((node, MenuItemTagName) => {
+ const menuItem = document.createElement(MenuItemTagName);
menuItem.role = 'menuitemradio';
menuItem.textContent = 'Radio item';
node.append(menuItem);
- });
+ }, MenuItemTagName);
await expect(menuItems).toHaveCount(5);
@@ -589,16 +594,16 @@ test.describe('MenuList', () => {
test.describe('`change` event', () => {
test('should emit `change` event when `checked` property changed', async ({ fastPage }) => {
const { element } = fastPage;
- const menuItems = element.locator('fluent-menu-item');
+ const menuItems = element.locator(MenuItemTagName);
- await fastPage.setTemplate(/* html */ `
-
- Menu Item 1
- Menu item 2
- Menu item 3
- Menu item 4
-
- `);
+ await fastPage.setTemplate({
+ innerHTML: /* html */ `
+ <${MenuItemTagName} role="menuitemradio">Menu Item 1${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 2${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 3${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 4${MenuItemTagName}>
+ `,
+ });
const [wasChanged] = await Promise.all([
menuItems
@@ -616,16 +621,18 @@ test.describe('MenuList', () => {
test('should emit change event when menu-item checked and unchecked', async ({ fastPage }) => {
const { element } = fastPage;
- const menuItems = element.locator('fluent-menu-item');
-
- await fastPage.setTemplate(/* html */ `
-
- Menu Item 1
- Menu item 2
- Menu item 3
- Menu item 4
-
- `);
+ const menuItems = element.locator(MenuItemTagName);
+
+ await fastPage.setTemplate({
+ innerHTML: /* html */ `
+ <${tagName}>
+ <${MenuItemTagName} role="menuitemradio">Menu Item 1${MenuItemTagName}>
+ <${MenuItemTagName} checked role="menuitemradio">Menu item 2${MenuItemTagName}>
+ <${MenuItemTagName} role="menuitemradio">Menu item 3${MenuItemTagName}>
+ <${MenuItemTagName} role="menuitemradio">Menu item 4${MenuItemTagName}>
+ ${tagName}>
+ `,
+ });
let wasChanged = menuItems.nth(0).evaluate((node: MenuItem) => {
return new Promise(resolve => {
diff --git a/packages/web-components/src/menu/menu.spec.ts b/packages/web-components/src/menu/menu.spec.ts
index 90aa168ed5d2de..01aa6d3a6b0c4f 100644
--- a/packages/web-components/src/menu/menu.spec.ts
+++ b/packages/web-components/src/menu/menu.spec.ts
@@ -1,18 +1,24 @@
import { expect, test } from '../../test/playwright/index.js';
+import { tagName as ButtonTagName } from '../button/button.options.js';
+import { tagName as DividerTagName } from '../divider/divider.options.js';
+import { tagName as MenuButtonTagName } from '../menu-button/menu-button.options.js';
+import { tagName as MenuItemTagName } from '../menu-item/menu-item.options.js';
+import { tagName as MenuListTagName } from '../menu-list/menu-list.options.js';
+import { tagName } from './menu.options.js';
test.describe('Menu', () => {
test.use({
innerHTML: /* html */ `
- Toggle Menu
-
- Menu item 1
- Menu item 2
- Menu item 3
- Menu item 4
-
+ <${MenuButtonTagName} appearance="primary" slot="trigger">Toggle Menu${MenuButtonTagName}>
+ <${MenuListTagName}>
+ <${MenuItemTagName}>Menu item 1${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 2${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 3${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 4${MenuItemTagName}>
+ ${MenuListTagName}>
`,
- tagName: 'fluent-menu',
- waitFor: ['fluent-menu-list', 'fluent-menu-item', 'fluent-menu-button'],
+ tagName,
+ waitFor: [MenuListTagName, MenuItemTagName, MenuButtonTagName, DividerTagName, ButtonTagName],
});
test('should create with document.createElement()', async ({ page, fastPage }) => {
@@ -24,24 +30,28 @@ test.describe('Menu', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-menu');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
test('should have menu-list be initially hidden', async ({ fastPage }) => {
const { element } = fastPage;
- const menuList = element.locator('fluent-menu-list');
+ const menuList = element.locator(MenuListTagName);
+
+ await fastPage.setTemplate();
await expect(menuList).toBeHidden();
});
test('should be visible when the button is clicked', async ({ fastPage }) => {
const { element } = fastPage;
- const menuButton = element.locator('fluent-menu-button');
- const menuList = element.locator('fluent-menu-list');
+ const menuButton = element.locator(MenuButtonTagName);
+ const menuList = element.locator(MenuListTagName);
+
+ await fastPage.setTemplate();
await menuButton.click();
@@ -50,8 +60,10 @@ test.describe('Menu', () => {
test('should be hidden when the button is clicked again', async ({ fastPage }) => {
const { element } = fastPage;
- const menuButton = element.locator('fluent-menu-button');
- const menuList = element.locator('fluent-menu-list');
+ const menuButton = element.locator(MenuButtonTagName);
+ const menuList = element.locator(MenuListTagName);
+
+ await fastPage.setTemplate();
await menuButton.click();
@@ -64,14 +76,18 @@ test.describe('Menu', () => {
test('should be hidden when an item is clicked', async ({ fastPage }) => {
const { element } = fastPage;
- const menuButton = element.locator('fluent-menu-button');
- const menuList = element.locator('fluent-menu-list');
- const menuItems = menuList.locator('fluent-menu-item');
+ const menuButton = element.locator(MenuButtonTagName);
+ const menuList = element.locator(MenuListTagName);
+ const menuItems = menuList.locator(MenuItemTagName);
+
+ await fastPage.setTemplate();
await menuButton.click();
await expect(menuList).toBeVisible();
+ await expect(menuItems.first()).toBeFocused();
+
await menuItems.first().click();
await expect(menuList).toBeHidden();
@@ -79,15 +95,17 @@ test.describe('Menu', () => {
test('should close when an item is focused and the enter key is pressed', async ({ fastPage, page }) => {
const { element } = fastPage;
- const menuButton = element.locator('fluent-menu-button');
- const menuList = element.locator('fluent-menu-list');
- const menuItems = menuList.locator('fluent-menu-item');
+ const menuButton = element.locator(MenuButtonTagName);
+ const menuList = element.locator(MenuListTagName);
+ const menuItems = menuList.locator(MenuItemTagName);
+
+ await fastPage.setTemplate();
await menuButton.click();
await expect(menuList).toBeVisible();
- await menuItems.first().focus();
+ await expect(menuItems.first()).toBeFocused();
await page.keyboard.press('Enter');
@@ -96,15 +114,17 @@ test.describe('Menu', () => {
test('should close when an item is focused and the escape key is pressed', async ({ fastPage, page }) => {
const { element } = fastPage;
- const menuButton = element.locator('fluent-menu-button');
- const menuList = element.locator('fluent-menu-list');
- const menuItems = menuList.locator('fluent-menu-item');
+ const menuButton = element.locator(MenuButtonTagName);
+ const menuList = element.locator(MenuListTagName);
+ const menuItems = menuList.locator(MenuItemTagName);
+
+ await fastPage.setTemplate();
await menuButton.click();
await expect(menuList).toBeVisible();
- await menuItems.first().focus();
+ await expect(menuItems.first()).toBeFocused();
await page.keyboard.press('Escape');
@@ -113,13 +133,18 @@ test.describe('Menu', () => {
test('should close when the mouse is clicked outside the menu', async ({ fastPage, page }) => {
const { element } = fastPage;
- const menuButton = element.locator('fluent-menu-button');
- const menuList = element.locator('fluent-menu-list');
+ const menuButton = element.locator(MenuButtonTagName);
+ const menuList = element.locator(MenuListTagName);
+ const menuItems = menuList.locator(MenuItemTagName);
+
+ await fastPage.setTemplate();
await menuButton.click();
await expect(menuList).toBeVisible();
+ await expect(menuItems.first()).toBeFocused();
+
await page.mouse.click(0, 0);
await expect(menuList).toBeHidden();
@@ -127,13 +152,18 @@ test.describe('Menu', () => {
test('should close when the escape key is pressed', async ({ fastPage, page }) => {
const { element } = fastPage;
- const menuButton = element.locator('fluent-menu-button');
- const menuList = element.locator('fluent-menu-list');
+ const menuButton = element.locator(MenuButtonTagName);
+ const menuList = element.locator(MenuListTagName);
+ const menuItems = menuList.locator(MenuItemTagName);
+
+ await fastPage.setTemplate();
await menuButton.click();
await expect(menuList).toBeVisible();
+ await expect(menuItems.first()).toBeFocused();
+
await page.keyboard.press('Escape');
await expect(menuList).toBeHidden();
@@ -141,13 +171,16 @@ test.describe('Menu', () => {
test('should close when the menu list loses keyboard focus', async ({ fastPage, page }) => {
const { element } = fastPage;
- const menuButton = element.locator('fluent-menu-button');
- const menuList = element.locator('fluent-menu-list');
- const menuItems = element.locator('fluent-menu-item');
+ const menuButton = element.locator(MenuButtonTagName);
+ const menuList = element.locator(MenuListTagName);
+ const menuItems = element.locator(MenuItemTagName);
+
+ await fastPage.setTemplate();
await menuButton.click();
await expect(menuList).toBeVisible();
+
await expect(menuItems.nth(0)).toBeFocused();
await page.keyboard.press('Tab');
@@ -157,8 +190,10 @@ test.describe('Menu', () => {
test('should NOT open on hover when the `openOnHover` property is false', async ({ fastPage }) => {
const { element } = fastPage;
- const menuButton = element.locator('fluent-menu-button');
- const menuList = element.locator('fluent-menu-list');
+ const menuButton = element.locator(MenuButtonTagName);
+ const menuList = element.locator(MenuListTagName);
+
+ await fastPage.setTemplate();
await expect(menuList).toBeHidden();
@@ -169,8 +204,8 @@ test.describe('Menu', () => {
test('should open on hover when the `openOnHover` property is true', async ({ fastPage }) => {
const { element } = fastPage;
- const menuButton = element.locator('fluent-menu-button');
- const menuList = element.locator('fluent-menu-list');
+ const menuButton = element.locator(MenuButtonTagName);
+ const menuList = element.locator(MenuListTagName);
await fastPage.setTemplate({ attributes: { 'open-on-hover': true } });
@@ -183,19 +218,22 @@ test.describe('Menu', () => {
test('should NOT open on context when the `openOnContext` property is false', async ({ fastPage }) => {
const { element } = fastPage;
- const menuButton = element.locator('fluent-menu-button');
- const menuList = element.locator('fluent-menu-list');
+ const menuButton = element.locator(MenuButtonTagName);
+ const menuList = element.locator(MenuListTagName);
+
+ await fastPage.setTemplate();
await expect(menuList).toBeHidden();
await menuButton.click({ button: 'right' });
+
await expect(menuList).toBeHidden();
});
test('should open on context when the `openOnContext` property is true', async ({ fastPage }) => {
const { element } = fastPage;
- const menuButton = element.locator('fluent-menu-button');
- const menuList = element.locator('fluent-menu-list');
+ const menuButton = element.locator(MenuButtonTagName);
+ const menuList = element.locator(MenuListTagName);
await fastPage.setTemplate({ attributes: { 'open-on-context': true } });
@@ -208,67 +246,64 @@ test.describe('Menu', () => {
test('should set popover attribute on slotted submenu', async ({ fastPage }) => {
const { element } = fastPage;
-
- const menuButton = element.locator('fluent-menu-button');
- const menuList = element.locator('fluent-menu-list:not([slot])');
- const menuItems = menuList.locator('fluent-menu-item');
-
- const submenuList = element.locator('fluent-menu-list[slot="submenu"]');
+ const menuButton = element.locator(MenuButtonTagName);
+ const menuList = element.locator(`${MenuListTagName}:not([slot])`);
+ const menuItems = menuList.locator(MenuItemTagName);
+ const submenuList = element.locator(`${MenuListTagName}[slot="submenu"]`);
await fastPage.setTemplate({
innerHTML: /* html */ `
- Toggle Menu
-
-
+ <${MenuButtonTagName} appearance="primary" slot="trigger">Toggle Menu${MenuButtonTagName}>
+ <${MenuListTagName}>
+ <${MenuItemTagName}>
Menu item 1
-
- Subitem 1
- Subitem 2
- Subitem 3
-
-
- Menu item 2
- Menu item 3
- Menu item 4
-
+ <${MenuListTagName} slot="submenu">
+ <${MenuItemTagName}> Subitem 1 ${MenuItemTagName}>
+ <${MenuItemTagName}> Subitem 2 ${MenuItemTagName}>
+ <${MenuItemTagName}> Subitem 3 ${MenuItemTagName}>
+ ${MenuListTagName}>
+ ${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 2${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 3${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 4${MenuItemTagName}>
+ ${MenuListTagName}>
`,
});
await menuButton.click();
- await menuItems.first().focus();
+ await expect(menuItems.first()).toBeFocused();
await element.press('ArrowRight');
await expect(submenuList).toBeVisible();
+
await expect(submenuList).toHaveAttribute('popover');
});
test('should focus the first item when a submenu is closed', async ({ fastPage }) => {
const { element } = fastPage;
-
- const menuButton = element.locator('fluent-menu-button');
- const menuList = element.locator('fluent-menu-list:not([slot])');
- const menuItems = menuList.locator('fluent-menu-item');
-
- const submenuList = element.locator('fluent-menu-list[slot="submenu"]');
+ const menuButton = element.locator(MenuButtonTagName);
+ const menuList = element.locator(`${MenuListTagName}:not([slot])`);
+ const menuItems = menuList.locator(MenuItemTagName);
+ const submenuList = element.locator(`${MenuListTagName}[slot="submenu"]`);
await fastPage.setTemplate({
innerHTML: /* html */ `
- Toggle Menu
-
-
+ <${MenuButtonTagName} appearance="primary" slot="trigger">Toggle Menu${MenuButtonTagName}>
+ <${MenuListTagName}>
+ <${MenuItemTagName}>
Menu item 1
-
- Subitem 1
- Subitem 2
- Subitem 3
-
-
- Menu item 2
- Menu item 3
- Menu item 4
-
+ <${MenuListTagName} slot="submenu">
+ <${MenuItemTagName}> Subitem 1 ${MenuItemTagName}>
+ <${MenuItemTagName}> Subitem 2 ${MenuItemTagName}>
+ <${MenuItemTagName}> Subitem 3 ${MenuItemTagName}>
+ ${MenuListTagName}>
+ ${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 2${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 3${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 4${MenuItemTagName}>
+ ${MenuListTagName}>
`,
});
@@ -278,7 +313,7 @@ test.describe('Menu', () => {
await expect(submenuList).toBeHidden();
- await menuItems.first().focus();
+ await expect(menuItems.first()).toBeFocused();
await element.press('ArrowRight');
@@ -295,38 +330,42 @@ test.describe('Menu', () => {
test('should focus trigger after menu is closed', async ({ fastPage, page }) => {
const { element } = fastPage;
- const menuButton = element.locator('fluent-menu-button');
-
- await fastPage.setTemplate(/* html */ `
-
-
- Primary Action
-
-
+ const menuButton = element.locator(MenuButtonTagName);
+ const menuList = element.locator(MenuListTagName);
+ const menuItems = menuList.locator(MenuItemTagName);
+
+ await fastPage.setTemplate({
+ innerHTML: /* html */ `
+ <${MenuButtonTagName} appearance="primary" slot="trigger" icon-only>${MenuButtonTagName}>
+ <${ButtonTagName} appearance="primary" slot="primary-action">Primary Action${ButtonTagName}>
+ <${MenuListTagName}>
+ <${MenuItemTagName}>
Item 1
-
- Subitem 1
- Subitem 2
-
-
+ <${MenuListTagName} slot="submenu">
+ <${MenuItemTagName}> Subitem 1 ${MenuItemTagName}>
+ <${MenuItemTagName}> Subitem 2 ${MenuItemTagName}>
+ ${MenuListTagName}>
+ ${MenuItemTagName}>
- Item 2
- Item 3
+ <${MenuItemTagName} role="menuitemcheckbox"> Item 2 ${MenuItemTagName}>
+ <${MenuItemTagName} role="menuitemcheckbox"> Item 3 ${MenuItemTagName}>
-
+ <${DividerTagName} role="separator" aria-orientation="horizontal" orientation="horizontal">${DividerTagName}>
- Menu item 4
- Menu item 5
- Menu item 6
+ <${MenuItemTagName}>Menu item 4${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 5${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 6${MenuItemTagName}>
- Menu item 7
- Menu item 8
-
-
- `);
+ <${MenuItemTagName}>Menu item 7${MenuItemTagName}>
+ <${MenuItemTagName}>Menu item 8${MenuItemTagName}>
+ ${MenuListTagName}>
+ `,
+ });
await menuButton.click();
+ await expect(menuItems.nth(0)).toBeFocused();
+
await page.keyboard.press('Escape');
await expect(menuButton).toBeFocused();
diff --git a/packages/web-components/src/message-bar/message-bar.spec.ts b/packages/web-components/src/message-bar/message-bar.spec.ts
index e255b2d3b73c91..907210cc913d92 100644
--- a/packages/web-components/src/message-bar/message-bar.spec.ts
+++ b/packages/web-components/src/message-bar/message-bar.spec.ts
@@ -1,11 +1,11 @@
import { expect, test } from '../../test/playwright/index.js';
import type { MessageBar } from './message-bar.js';
-import { MessageBarIntent, MessageBarLayout, MessageBarShape } from './message-bar.options.js';
+import { MessageBarIntent, MessageBarLayout, MessageBarShape, tagName } from './message-bar.options.js';
test.describe('Message Bar', () => {
test.use({
- tagName: 'fluent-message-bar',
- waitFor: ['fluent-button'],
+ tagName,
+ innerHTML: 'Message Bar',
});
test('should create with document.createElement()', async ({ page, fastPage }) => {
@@ -17,9 +17,9 @@ test.describe('Message Bar', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-message-bar');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -27,15 +27,19 @@ test.describe('Message Bar', () => {
test('should include a role of status', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).toHaveJSProperty('elementInternals.role', 'status');
});
test('should set the `intent` property to match the `intent` attribute', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const intent of Object.values(MessageBarIntent)) {
await test.step(intent, async () => {
- await fastPage.setTemplate({ attributes: { intent } });
+ await fastPage.updateTemplate(element, { attributes: { intent } });
await expect(element).toHaveJSProperty('intent', intent);
@@ -47,9 +51,11 @@ test.describe('Message Bar', () => {
test('should set the `shape` property to match the `shape` attribute', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const shape of Object.values(MessageBarShape)) {
await test.step(shape, async () => {
- await fastPage.setTemplate({ attributes: { shape } });
+ await fastPage.updateTemplate(element, { attributes: { shape } });
await expect(element).toHaveJSProperty('shape', shape);
@@ -58,13 +64,14 @@ test.describe('Message Bar', () => {
}
});
- // @FIXME: This test is failing on OSX - https://github.com/microsoft/fluentui/issues/33172
test('should set the `layout` property to match the `layout` attribute', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const layout of Object.values(MessageBarLayout)) {
await test.step(layout, async () => {
- await fastPage.setTemplate({ attributes: { layout } });
+ await fastPage.updateTemplate(element, { attributes: { layout } });
await expect(element).toHaveJSProperty('layout', layout);
@@ -76,6 +83,8 @@ test.describe('Message Bar', () => {
test('should emit a `dismiss` event when `dismissMessageBar()` is called', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
const didDismiss = element.evaluate(
node => new Promise(resolve => node.addEventListener('dismiss', () => resolve(true))),
);
diff --git a/packages/web-components/src/option/option.spec.ts b/packages/web-components/src/option/option.spec.ts
index 13574e5ca3869f..f7617f3ca42f81 100644
--- a/packages/web-components/src/option/option.spec.ts
+++ b/packages/web-components/src/option/option.spec.ts
@@ -1,9 +1,10 @@
import { expect, test } from '../../test/playwright/index.js';
import type { DropdownOption } from './option.js';
+import { tagName } from './option.options.js';
test.describe('DropdownOption', () => {
test.use({
- tagName: 'fluent-option',
+ tagName,
innerHTML: 'Option',
});
@@ -16,9 +17,9 @@ test.describe('DropdownOption', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-option');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -160,7 +161,7 @@ test.describe('DropdownOption', () => {
await fastPage.setTemplate(/* html */ `
`);
diff --git a/packages/web-components/src/progress-bar/progress-bar.spec.ts b/packages/web-components/src/progress-bar/progress-bar.spec.ts
index fa6f1823f02960..66e5bab756af15 100644
--- a/packages/web-components/src/progress-bar/progress-bar.spec.ts
+++ b/packages/web-components/src/progress-bar/progress-bar.spec.ts
@@ -1,6 +1,6 @@
import { expect, test } from '../../test/playwright/index.js';
import type { ProgressBar } from './progress-bar.js';
-import { ProgressBarShape, ProgressBarThickness, ProgressBarValidationState } from './progress-bar.options.js';
+import { ProgressBarShape, ProgressBarThickness, ProgressBarValidationState, tagName } from './progress-bar.options.js';
interface BoundingBox {
width: number;
@@ -8,7 +8,7 @@ interface BoundingBox {
test.describe('Progress Bar', () => {
test.use({
- tagName: 'fluent-progress-bar',
+ tagName,
});
test('should create with document.createElement()', async ({ page, fastPage }) => {
@@ -20,9 +20,9 @@ test.describe('Progress Bar', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-progress-bar');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -30,6 +30,8 @@ test.describe('Progress Bar', () => {
test('should include a role of progressbar', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).toHaveJSProperty('elementInternals.role', 'progressbar');
});
@@ -59,6 +61,9 @@ test.describe('Progress Bar', () => {
test('should set indicator width to be 1/3 of the container width if `value` is missing', async ({ fastPage }) => {
const { element } = fastPage;
+
+ await fastPage.setTemplate();
+
await element.evaluate(node => {
node.style.setProperty('width', '100px');
});
diff --git a/packages/web-components/src/radio-group/radio-group.spec.ts b/packages/web-components/src/radio-group/radio-group.spec.ts
index 56dea1212bc9ff..6b581d079c232b 100644
--- a/packages/web-components/src/radio-group/radio-group.spec.ts
+++ b/packages/web-components/src/radio-group/radio-group.spec.ts
@@ -1,12 +1,13 @@
import { expect, test } from '../../test/playwright/index.js';
import type { Radio } from '../radio/index.js';
+import { tagName as RadioTagName } from '../radio/radio.options.js';
import type { RadioGroup } from './radio-group.js';
+import { tagName } from './radio-group.options.js';
test.describe('RadioGroup', () => {
test.use({
- tagName: 'fluent-radio-group',
- waitFor: ['fluent-radio'],
- innerHTML: '',
+ tagName,
+ waitFor: [RadioTagName],
});
test('should create with document.createElement()', async ({ page, fastPage }) => {
@@ -18,9 +19,9 @@ test.describe('RadioGroup', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-radio-group');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -67,13 +68,13 @@ test.describe('RadioGroup', () => {
test('should set the `aria-setsize` and `aria-posinset` attributes on the radios', async ({ fastPage }) => {
const { element } = fastPage;
- const radios = element.locator('fluent-radio');
+ const radios = element.locator(RadioTagName);
await fastPage.setTemplate({
innerHTML: /* html */ `
-
-
-
+ <${RadioTagName}>${RadioTagName}>
+ <${RadioTagName}>${RadioTagName}>
+ <${RadioTagName}>${RadioTagName}>
`,
});
@@ -91,16 +92,16 @@ test.describe('RadioGroup', () => {
fastPage,
}) => {
const { element } = fastPage;
- const radios = element.locator('fluent-radio');
+ const radios = element.locator(RadioTagName);
const firstRadio = radios.nth(0);
const secondRadio = radios.nth(1);
const thirdRadio = radios.nth(2);
await fastPage.setTemplate({
innerHTML: /* html */ `
-
-
-
+ <${RadioTagName}>${RadioTagName}>
+ <${RadioTagName} disabled>${RadioTagName}>
+ <${RadioTagName}>${RadioTagName}>
`,
});
@@ -133,11 +134,11 @@ test.describe('RadioGroup', () => {
await fastPage.setTemplate(/* html */ `
-
-
-
-
-
+ <${tagName} disabled>
+ <${RadioTagName}>${RadioTagName}>
+ <${RadioTagName}>${RadioTagName}>
+ <${RadioTagName}>${RadioTagName}>
+ ${tagName}>
`);
@@ -154,16 +155,16 @@ test.describe('RadioGroup', () => {
test('should NOT be focusable via click when disabled', async ({ fastPage, page }) => {
const { element } = fastPage;
- const radios = element.locator('fluent-radio');
+ const radios = element.locator(RadioTagName);
const button = page.locator('button', { hasText: 'Button' });
await fastPage.setTemplate(/* html */ `
-
-
-
-
-
+ <${tagName}>
+ <${RadioTagName}>${RadioTagName}>
+ <${RadioTagName}>${RadioTagName}>
+ <${RadioTagName}>${RadioTagName}>
+ ${tagName}>
`);
await button.focus();
@@ -200,16 +201,16 @@ test.describe('RadioGroup', () => {
test('should set tabindex of 0 to a child radio with a matching `value`', async ({ fastPage }) => {
const { element } = fastPage;
- const radios = element.locator('fluent-radio');
+ const radios = element.locator(RadioTagName);
await fastPage.setTemplate({
attributes: {
value: 'foo',
},
innerHTML: /* html */ `
-
-
-
+ <${RadioTagName} value="foo">${RadioTagName}>
+ <${RadioTagName} value="bar">${RadioTagName}>
+ <${RadioTagName} value="baz">${RadioTagName}>
`,
});
@@ -218,13 +219,13 @@ test.describe('RadioGroup', () => {
test("should set tabindex of 0 to a child radio that's initially checked", async ({ fastPage }) => {
const { element } = fastPage;
- const radios = element.locator('fluent-radio');
+ const radios = element.locator(RadioTagName);
await fastPage.setTemplate({
innerHTML: /* html */ `
-
-
-
+ <${RadioTagName} value="foo">${RadioTagName}>
+ <${RadioTagName} value="bar" checked>${RadioTagName}>
+ <${RadioTagName} value="baz">${RadioTagName}>
`,
});
@@ -233,13 +234,13 @@ test.describe('RadioGroup', () => {
test('should check the first radio with a matching `value`', async ({ fastPage }) => {
const { element } = fastPage;
- const radios = element.locator('fluent-radio');
+ const radios = element.locator(RadioTagName);
await fastPage.setTemplate(/* html */ `
-
-
-
-
+ <${tagName} value="bar">
+ <${RadioTagName} id="radio-1" name="radio" value="foo">${RadioTagName}>
+ <${RadioTagName} id="radio-2" name="radio" value="bar">${RadioTagName}>
+ <${RadioTagName} id="radio-3" name="radio" value="baz">${RadioTagName}>
`);
await expect(radios.nth(0)).toHaveJSProperty('checked', false);
@@ -254,14 +255,14 @@ test.describe('RadioGroup', () => {
page,
}) => {
const { element } = fastPage;
- const radios = element.locator('fluent-radio');
+ const radios = element.locator(RadioTagName);
await fastPage.setTemplate(/* html */ `
-
-
-
-
-
+ <${tagName}>
+ <${RadioTagName} id="radio-1" name="radio" value="foo">${RadioTagName}>
+ <${RadioTagName} id="radio-2" name="radio" value="bar">${RadioTagName}>
+ <${RadioTagName} id="radio-3" name="radio" value="baz">${RadioTagName}>
+ ${tagName}>
`);
await radios.nth(0).evaluate((node: Radio) => {
@@ -283,16 +284,16 @@ test.describe('RadioGroup', () => {
});
test('should emit `change` event when using keyboard', async ({ fastPage, page }) => {
- const element = page.locator('fluent-radio-group');
- const radios = element.locator('fluent-radio');
+ const element = page.locator(tagName);
+ const radios = element.locator(RadioTagName);
- await fastPage.setTemplate(/* html */ `
-
-
-
-
-
- `);
+ await fastPage.setTemplate({
+ innerHTML: /* html */ `
+ <${RadioTagName} id="radio-1" name="radio" value="foo">${RadioTagName}>
+ <${RadioTagName} id="radio-2" name="radio" value="bar">${RadioTagName}>
+ <${RadioTagName} id="radio-3" name="radio" value="baz">${RadioTagName}>
+ `,
+ });
const wasChanged = element.evaluate((node: RadioGroup) => {
return new Promise(resolve => {
@@ -308,16 +309,16 @@ test.describe('RadioGroup', () => {
test('should set a child radio with a matching `value` to `checked` when value changes', async ({ fastPage }) => {
const { element } = fastPage;
- const radios = element.locator('fluent-radio');
+ const radios = element.locator(RadioTagName);
await fastPage.setTemplate({
attributes: {
value: 'foo',
},
innerHTML: /* html */ `
-
-
-
+ <${RadioTagName} value="foo">${RadioTagName}>
+ <${RadioTagName} value="bar">${RadioTagName}>
+ <${RadioTagName} value="baz">${RadioTagName}>
`,
});
@@ -334,13 +335,13 @@ test.describe('RadioGroup', () => {
test('should mark only the last radio defaulted to checked as checked', async ({ fastPage }) => {
const { element } = fastPage;
- const radios = element.locator('fluent-radio');
+ const radios = element.locator(RadioTagName);
await fastPage.setTemplate({
innerHTML: /* html */ `
-
-
-
+ <${RadioTagName} value="foo" checked>${RadioTagName}>
+ <${RadioTagName} value="bar" checked>${RadioTagName}>
+ <${RadioTagName} value="baz" checked>${RadioTagName}>
`,
});
@@ -355,14 +356,14 @@ test.describe('RadioGroup', () => {
test('should mark radio matching value on radio-group over any checked attributes', async ({ fastPage }) => {
const { element } = fastPage;
- const radios = element.locator('fluent-radio');
+ const radios = element.locator(RadioTagName);
await fastPage.setTemplate({
attributes: { value: 'foo' },
innerHTML: /* html */ `
-
-
-
+ <${RadioTagName} value="foo">${RadioTagName}>
+ <${RadioTagName} value="bar" checked>${RadioTagName}>
+ <${RadioTagName} value="baz">${RadioTagName}>
`,
});
@@ -379,15 +380,15 @@ test.describe('RadioGroup', () => {
test('should allow resetting of elements by the parent form', async ({ fastPage, page }) => {
const { element } = fastPage;
- const radios = element.locator('fluent-radio');
+ const radios = element.locator(RadioTagName);
await fastPage.setTemplate(/* html */ `
`);
@@ -420,13 +421,13 @@ test.describe('RadioGroup', () => {
test('should focus the first radio when the radio group is focused', async ({ fastPage, page }) => {
const { element } = fastPage;
- const radios = element.locator('fluent-radio');
+ const radios = element.locator(RadioTagName);
await fastPage.setTemplate({
innerHTML: /* html */ `
-
-
-
+ <${RadioTagName}>${RadioTagName}>
+ <${RadioTagName}>${RadioTagName}>
+ <${RadioTagName}>${RadioTagName}>
`,
});
@@ -440,13 +441,13 @@ test.describe('RadioGroup', () => {
page,
}) => {
const { element } = fastPage;
- const radios = element.locator('fluent-radio');
+ const radios = element.locator(RadioTagName);
await fastPage.setTemplate({
innerHTML: /* html */ `
-
-
-
+ <${RadioTagName} disabled>${RadioTagName}>
+ <${RadioTagName}>${RadioTagName}>
+ <${RadioTagName}>${RadioTagName}>
`,
});
@@ -460,13 +461,13 @@ test.describe('RadioGroup', () => {
page,
}) => {
const { element } = fastPage;
- const radios = element.locator('fluent-radio');
+ const radios = element.locator(RadioTagName);
await fastPage.setTemplate({
innerHTML: /* html */ `
-
-
-
+ <${RadioTagName} disabled>${RadioTagName}>
+ <${RadioTagName} disabled>${RadioTagName}>
+ <${RadioTagName}>${RadioTagName}>
`,
});
@@ -483,9 +484,9 @@ test.describe('RadioGroup', () => {
await fastPage.setTemplate({
innerHTML: /* html */ `
-
-
-
+ <${RadioTagName} disabled>${RadioTagName}>
+ <${RadioTagName} disabled>${RadioTagName}>
+ <${RadioTagName} disabled>${RadioTagName}>
`,
});
@@ -494,21 +495,20 @@ test.describe('RadioGroup', () => {
await expect(element).not.toBeFocused();
});
- // @FIXME: This test is failing on OSX - https://github.com/microsoft/fluentui/issues/33172
test('should move focus to the next radio when the radio group is focused and the arrow down key is pressed', async ({
fastPage,
page,
}) => {
const { element } = fastPage;
- const radios = element.locator('fluent-radio');
+ const radios = element.locator(RadioTagName);
await fastPage.setTemplate(/* html */ `
-
-
-
-
-
+ <${tagName}>
+ <${RadioTagName}>${RadioTagName}>
+ <${RadioTagName}>${RadioTagName}>
+ <${RadioTagName}>${RadioTagName}>
+ ${tagName}>
`);
await page.getByTestId('before').focus();
@@ -540,9 +540,9 @@ test.describe('RadioGroup', () => {
await fastPage.setTemplate({
innerHTML: /* html */ `
-
-
-
+ <${RadioTagName} name="foo">${RadioTagName}>
+ <${RadioTagName} name="foo">${RadioTagName}>
+ <${RadioTagName} name="foo">${RadioTagName}>
`,
});
@@ -556,28 +556,27 @@ test.describe('RadioGroup', () => {
await fastPage.setTemplate({
innerHTML: /* html */ `
-
-
-
+ <${RadioTagName} name="foo">${RadioTagName}>
+ <${RadioTagName} name="bar">${RadioTagName}>
+ <${RadioTagName} name="baz">${RadioTagName}>
`,
});
await expect(element).not.toHaveAttribute('name');
});
- // @FIXME: This test is failing on OSX - https://github.com/microsoft/fluentui/issues/33172
test('should set the `name` attribute of the radios to the `name` attribute of the radio group', async ({
fastPage,
}) => {
const { element } = fastPage;
- const radios = element.locator('fluent-radio');
+ const radios = element.locator(RadioTagName);
await fastPage.setTemplate({
attributes: { name: 'foo' },
innerHTML: /* html */ `
-
-
-
+ <${RadioTagName}>${RadioTagName}>
+ <${RadioTagName}>${RadioTagName}>
+ <${RadioTagName}>${RadioTagName}>
`,
});
@@ -592,14 +591,14 @@ test.describe('RadioGroup', () => {
fastPage,
}) => {
const { element } = fastPage;
- const radios = element.locator('fluent-radio');
+ const radios = element.locator(RadioTagName);
await fastPage.setTemplate({
attributes: { name: 'foo' },
innerHTML: /* html */ `
-
-
-
+ <${RadioTagName} name="bar">${RadioTagName}>
+ <${RadioTagName} name="baz">${RadioTagName}>
+ <${RadioTagName} name="qux">${RadioTagName}>
`,
});
@@ -617,15 +616,15 @@ test.describe('RadioGroup', () => {
page,
}) => {
const { element } = fastPage;
- const radios = element.locator('fluent-radio');
+ const radios = element.locator(RadioTagName);
await fastPage.setTemplate(/* html */ `
`);
@@ -644,15 +643,15 @@ test.describe('RadioGroup', () => {
page,
}) => {
const { element } = fastPage;
- const radios = element.locator('fluent-radio');
+ const radios = element.locator(RadioTagName);
await fastPage.setTemplate(/* html */ `
`);
@@ -671,15 +670,15 @@ test.describe('RadioGroup', () => {
page,
}) => {
const { element } = fastPage;
- const radios = element.locator('fluent-radio');
+ const radios = element.locator(RadioTagName);
await fastPage.setTemplate(/* html */ `
`);
@@ -699,7 +698,7 @@ test.describe('RadioGroup', () => {
}) => {
await fastPage.setTemplate(/* html */ `
`);
@@ -716,16 +715,16 @@ test.describe('RadioGroup', () => {
page,
}) => {
const { element } = fastPage;
- const radios = element.locator('fluent-radio');
+ const radios = element.locator(RadioTagName);
const button = page.locator('button');
await fastPage.setTemplate(/* html */ `
`);
@@ -744,16 +743,16 @@ test.describe('RadioGroup', () => {
page,
}) => {
const { element } = fastPage;
- const radios = element.locator('fluent-radio');
+ const radios = element.locator(RadioTagName);
const before = page.getByTestId('before');
await fastPage.setTemplate(/* html */ `
-
-
-
-
-
+ <${tagName} name="radio">
+ <${RadioTagName} value="foo">${RadioTagName}>
+ <${RadioTagName} value="bar">${RadioTagName}>
+ <${RadioTagName} value="baz">${RadioTagName}>
+ ${tagName}>
`);
await before.focus();
@@ -771,16 +770,16 @@ test.describe('RadioGroup', () => {
page,
}) => {
const { element } = fastPage;
- const radios = element.locator('fluent-radio');
+ const radios = element.locator(RadioTagName);
const before = page.getByTestId('before');
await fastPage.setTemplate(/* html */ `
-
-
-
-
-
+ <${tagName} name="radio">
+ <${RadioTagName} value="foo">${RadioTagName}>
+ <${RadioTagName} value="bar">${RadioTagName}>
+ <${RadioTagName} value="baz">${RadioTagName}>
+ ${tagName}>
`);
await before.focus();
diff --git a/packages/web-components/src/radio/radio.spec.ts b/packages/web-components/src/radio/radio.spec.ts
index e66920b60ab9da..7d329a057054de 100644
--- a/packages/web-components/src/radio/radio.spec.ts
+++ b/packages/web-components/src/radio/radio.spec.ts
@@ -1,8 +1,11 @@
import { expect, test } from '../../test/playwright/index.js';
import type { Radio } from './radio.js';
+import { tagName } from './radio.options.js';
test.describe('Radio', () => {
- test.use({ tagName: 'fluent-radio' });
+ test.use({
+ tagName,
+ });
test('should have a role of `radio`', async ({ fastPage }) => {
const { element } = fastPage;
@@ -21,9 +24,9 @@ test.describe('Radio', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-radio');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -87,12 +90,12 @@ test.describe('Radio', () => {
test('should initialize to the provided value attribute if set pre-connection', async ({ fastPage, page }) => {
await fastPage.setTemplate('');
- const value = await page.evaluate(() => {
- const radio = document.createElement('fluent-radio') as Radio;
+ const value = await page.evaluate(tagName => {
+ const radio = document.createElement(tagName) as Radio;
radio.setAttribute('value', 'foo');
return radio.value;
- });
+ }, tagName);
expect(value).toBe('foo');
});
@@ -157,7 +160,7 @@ test.describe('Radio', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -180,7 +183,7 @@ test.describe('Radio', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -212,7 +215,7 @@ test.describe('Radio', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -242,7 +245,7 @@ test.describe('Radio', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -267,7 +270,7 @@ test.describe('Radio', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -295,7 +298,7 @@ test.describe('Radio', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -325,7 +328,7 @@ test.describe('Radio', () => {
await fastPage.setTemplate(/* html */ `
`);
diff --git a/packages/web-components/src/rating-display/rating-display.spec.ts b/packages/web-components/src/rating-display/rating-display.spec.ts
index 388350316676ea..d21bac63afafe8 100644
--- a/packages/web-components/src/rating-display/rating-display.spec.ts
+++ b/packages/web-components/src/rating-display/rating-display.spec.ts
@@ -1,6 +1,6 @@
import { expect, test } from '../../test/playwright/index.js';
-import { RatingDisplaySize } from './rating-display.options.js';
import type { RatingDisplay } from './rating-display.js';
+import { RatingDisplaySize, tagName } from './rating-display.options.js';
function encodedSvg(str: string, browserName: string) {
return encodeURIComponent(str)
@@ -10,7 +10,7 @@ function encodedSvg(str: string, browserName: string) {
test.describe('Rating Display', () => {
test.use({
- tagName: 'fluent-rating-display',
+ tagName,
});
test('should create with document.createElement()', async ({ page, fastPage }) => {
@@ -22,15 +22,18 @@ test.describe('Rating Display', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-rating-display');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
test('should not set any default attributes and custom states', async ({ fastPage }) => {
const { element } = fastPage;
+
+ await fastPage.setTemplate();
+
await expect(element).toBeVisible();
for (const attribute of ['color', 'compact', 'count', 'icon-view-box', 'max', 'size']) {
await expect(element).not.toHaveAttribute(attribute);
diff --git a/packages/web-components/src/slider/slider.spec.ts b/packages/web-components/src/slider/slider.spec.ts
index e49fa9e18ef10d..01b35c8aa758e6 100644
--- a/packages/web-components/src/slider/slider.spec.ts
+++ b/packages/web-components/src/slider/slider.spec.ts
@@ -1,6 +1,6 @@
import { expect, test } from '../../test/playwright/index.js';
import type { Slider } from './slider.js';
-import { SliderSize } from './slider.options.js';
+import { SliderSize, tagName } from './slider.options.js';
interface BoundingBox {
x: number;
@@ -11,11 +11,9 @@ interface BoundingBox {
test.describe('Slider', () => {
test.use({
- tagName: 'fluent-slider',
+ tagName,
});
- // Foundation tests
-
test('should create with document.createElement()', async ({ page, fastPage }) => {
await fastPage.setTemplate();
@@ -25,9 +23,9 @@ test.describe('Slider', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-slider');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -35,6 +33,8 @@ test.describe('Slider', () => {
test('should have a default role of `slider`', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).toHaveJSProperty('elementInternals.role', 'slider');
});
@@ -43,6 +43,8 @@ test.describe('Slider', () => {
}) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).toHaveJSProperty('min', '');
await expect(element).toHaveJSProperty('max', '');
@@ -55,7 +57,7 @@ test.describe('Slider', () => {
await fastPage.setTemplate(/* html */ `
-
+ <${tagName} id="slider">${tagName}>
`);
@@ -69,6 +71,8 @@ test.describe('Slider', () => {
test('should set a `tabindex` of 0', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).toHaveAttribute('tabindex', '0');
});
@@ -77,12 +81,16 @@ test.describe('Slider', () => {
}) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).toHaveJSProperty('elementInternals.ariaOrientation', 'horizontal');
});
test('should initialize to the initial value if no value property is set', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).toHaveJSProperty('value', '50');
});
@@ -91,6 +99,8 @@ test.describe('Slider', () => {
}) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).toHaveJSProperty('elementInternals.ariaDisabled', 'false');
});
@@ -105,6 +115,8 @@ test.describe('Slider', () => {
test('should set the `elementInternals.ariaDisabled` when `disabled` property is true', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).toHaveJSProperty('elementInternals.ariaDisabled', 'false');
await element.evaluate((node: Slider) => {
@@ -129,7 +141,7 @@ test.describe('Slider', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -219,6 +231,8 @@ test.describe('Slider', () => {
test('should allow setting value with number', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await element.evaluate((node: Slider) => {
node.valueAsNumber = 8;
});
@@ -240,6 +254,8 @@ test.describe('Slider', () => {
}) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await element.evaluate((node: Slider) => {
node.valueTextFormatter = () => 'Seventy Five Years';
});
@@ -317,7 +333,7 @@ test.describe('Slider', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -343,7 +359,7 @@ test.describe('Slider', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -437,13 +453,13 @@ test.describe('Slider', () => {
await fastPage.setTemplate('');
- await page.evaluate(() => {
- const slider = document.createElement('fluent-slider') as Slider;
+ await page.evaluate(tagName => {
+ const slider = document.createElement(tagName) as Slider;
slider.value = '3';
document.body.appendChild(slider);
- });
+ }, tagName);
await expect(element).toHaveJSProperty('value', '3');
await expect(element).toHaveJSProperty('elementInternals.ariaValueNow', '3');
@@ -452,6 +468,8 @@ test.describe('Slider', () => {
test('should initialize to the provided value attribute when set post-connection', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await element.evaluate((node: Slider) => {
node.setAttribute('value', '3');
});
@@ -488,7 +506,7 @@ test.describe('Slider', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -515,7 +533,7 @@ test.describe('Slider', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -548,7 +566,7 @@ test.describe('Slider', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -580,6 +598,8 @@ test.describe('Slider', () => {
test('should emit `change` event when `value` property changed', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
const wasChanged = element.evaluate(
node => new Promise(resolve => node.addEventListener('change', () => resolve(true))),
);
@@ -594,6 +614,8 @@ test.describe('Slider', () => {
test('should emit `change` event if the `value` attribute changed', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
const wasChanged = element.evaluate(
node => new Promise(resolve => node.addEventListener('change', () => resolve(true))),
);
@@ -662,6 +684,8 @@ test.describe('Slider', () => {
}) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
const track = element.locator('.track');
const thumb = element.locator('.thumb-container');
const trackBox = (await track.boundingBox()) as BoundingBox;
@@ -816,7 +840,7 @@ test.describe('Slider', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -847,6 +871,8 @@ test.describe('Slider', () => {
const { element } = fastPage;
const thumb = element.locator('.thumb-container');
+ await fastPage.setTemplate();
+
await expect(element).toHaveJSProperty('valueAsNumber', 50);
await thumb.click();
diff --git a/packages/web-components/src/spinner/spinner.spec.ts b/packages/web-components/src/spinner/spinner.spec.ts
index 693e25f65ec57d..ce446dbc7bbff3 100644
--- a/packages/web-components/src/spinner/spinner.spec.ts
+++ b/packages/web-components/src/spinner/spinner.spec.ts
@@ -1,9 +1,9 @@
import { expect, test } from '../../test/playwright/index.js';
-import { SpinnerAppearance, SpinnerSize } from './spinner.options.js';
+import { SpinnerAppearance, SpinnerSize, tagName } from './spinner.options.js';
test.describe('Spinner', () => {
test.use({
- tagName: 'fluent-spinner',
+ tagName,
});
test('should create with document.createElement()', async ({ page, fastPage }) => {
@@ -15,9 +15,9 @@ test.describe('Spinner', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-spinner');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -25,9 +25,11 @@ test.describe('Spinner', () => {
test('should set the `appearance` property to match the `appearance` attribute', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const appearance of Object.values(SpinnerAppearance)) {
await test.step(appearance, async () => {
- await fastPage.setTemplate({ attributes: { appearance } });
+ await fastPage.updateTemplate(element, { attributes: { appearance } });
await expect(element).toHaveJSProperty('appearance', appearance);
@@ -39,9 +41,11 @@ test.describe('Spinner', () => {
test('should set the `size` property to match the `size` attribute', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const size of Object.values(SpinnerSize)) {
await test.step(size, async () => {
- await fastPage.setTemplate({ attributes: { size } });
+ await fastPage.updateTemplate(element, { attributes: { size } });
await expect(element).toHaveJSProperty('size', size);
diff --git a/packages/web-components/src/switch/switch.spec.ts b/packages/web-components/src/switch/switch.spec.ts
index 3411289c7e1605..98478ce7fabb8d 100644
--- a/packages/web-components/src/switch/switch.spec.ts
+++ b/packages/web-components/src/switch/switch.spec.ts
@@ -1,8 +1,9 @@
import { expect, test } from '../../test/playwright/index.js';
import type { Switch } from './switch.js';
+import { tagName } from './switch.options.js';
test.describe('Switch', () => {
- test.use({ tagName: 'fluent-switch' });
+ test.use({ tagName: tagName });
test('should create with document.createElement()', async ({ page, fastPage }) => {
await fastPage.setTemplate();
@@ -13,9 +14,9 @@ test.describe('Switch', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-switch');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -23,12 +24,16 @@ test.describe('Switch', () => {
test('should have a role of `switch`', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).toHaveJSProperty('elementInternals.role', 'switch');
});
test('should set the `ariaChecked` property to `false` when `checked` is not defined', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).not.toHaveAttribute('checked');
await expect(element).toHaveJSProperty('elementInternals.ariaChecked', 'false');
@@ -51,6 +56,8 @@ test.describe('Switch', () => {
test('should NOT set a default `aria-required` value when `required` is not defined', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).not.toHaveAttribute('required');
await expect(element).not.toHaveAttribute('aria-required');
@@ -59,6 +66,8 @@ test.describe('Switch', () => {
test('should be focusable by default', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await element.focus();
await expect(element).toBeFocused();
@@ -77,6 +86,8 @@ test.describe('Switch', () => {
test('should initialize to the initial value if no `value` property is set', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).toHaveJSProperty('value', 'on');
});
@@ -93,6 +104,8 @@ test.describe('Switch', () => {
const expectedValue = 'foobar';
+ await fastPage.setTemplate();
+
await element.evaluate((node: Switch, expectedValue) => {
node.setAttribute('value', expectedValue);
}, expectedValue);
@@ -101,17 +114,20 @@ test.describe('Switch', () => {
});
test('should initialize to the provided `value` property when set pre-connection', async ({ fastPage, page }) => {
- await fastPage.setTemplate('');
-
const expectedValue = 'foobar';
- const value = await page.evaluate(expectedValue => {
- const node = document.createElement('fluent-switch') as Switch;
+ await fastPage.setTemplate('');
+
+ const value = await page.evaluate(
+ ([expectedValue, tagName]) => {
+ const node = document.createElement(tagName) as Switch;
- node.value = expectedValue;
+ node.value = expectedValue;
- return node.value;
- }, expectedValue);
+ return node.value;
+ },
+ [expectedValue, tagName],
+ );
expect(value).toBe(expectedValue);
});
@@ -121,7 +137,7 @@ test.describe('Switch', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -133,7 +149,7 @@ test.describe('Switch', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -150,7 +166,7 @@ test.describe('Switch', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -175,7 +191,7 @@ test.describe('Switch', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -203,7 +219,7 @@ test.describe('Switch', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -233,7 +249,7 @@ test.describe('Switch', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -246,15 +262,15 @@ test.describe('Switch', () => {
});
test('should submit the values of multiple switches when checked', async ({ fastPage, page }) => {
- const switches = page.locator('fluent-switch');
+ const switches = page.locator(tagName);
const element1 = switches.nth(0);
const element2 = switches.nth(1);
const submitButton = page.locator('button');
await fastPage.setTemplate(/* html */ `
`);
diff --git a/packages/web-components/src/tab/tab.spec.ts b/packages/web-components/src/tab/tab.spec.ts
index 2b46355e147092..5e905f3e874651 100644
--- a/packages/web-components/src/tab/tab.spec.ts
+++ b/packages/web-components/src/tab/tab.spec.ts
@@ -1,7 +1,11 @@
import { expect, test } from '../../test/playwright/index.js';
+import { tagName } from './tab.options.js';
test.describe('Tab', () => {
- test.use({ tagName: 'fluent-tab' });
+ test.use({
+ tagName,
+ innerHTML: 'Tab',
+ });
test('should create with document.createElement()', async ({ page, fastPage }) => {
await fastPage.setTemplate('');
@@ -12,9 +16,9 @@ test.describe('Tab', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-tab');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
diff --git a/packages/web-components/src/tablist/tablist.spec.ts b/packages/web-components/src/tablist/tablist.spec.ts
index 7cbf89f3ea5d9e..6878e54aa64f96 100644
--- a/packages/web-components/src/tablist/tablist.spec.ts
+++ b/packages/web-components/src/tablist/tablist.spec.ts
@@ -1,20 +1,21 @@
import { expect, test } from '../../test/playwright/index.js';
import type { Tab } from '../tab/tab.js';
+import { tagName as TabTagName } from '../tab/tab.options.js';
import type { Tablist } from './tablist.js';
-import { TablistAppearance, TablistSize } from './tablist.options.js';
+import { TablistAppearance, TablistSize, tagName } from './tablist.options.js';
test.describe('Tablist', () => {
test.use({
- tagName: 'fluent-tablist',
- waitFor: ['fluent-tab'],
+ tagName,
innerHTML: /* html */ `
- Tab one
- Tab two
- Tab three
+ <${TabTagName}>Tab one${TabTagName}>
+ <${TabTagName}>Tab two${TabTagName}>
+ <${TabTagName}>Tab three${TabTagName}>
`,
+ waitFor: [TabTagName],
});
- test('should create with document.createElement()', async ({ page, fastPage }) => {
+ test('should create with document.createElement()', async ({ page, fastPage, innerHTML }) => {
await fastPage.setTemplate();
let hasError = false;
@@ -23,9 +24,9 @@ test.describe('Tablist', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-tablist');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -33,6 +34,8 @@ test.describe('Tablist', () => {
test('should have reflect disabled attribute on control', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).not.toHaveAttribute('disabled');
await element.evaluate((node: Tablist) => {
@@ -44,7 +47,9 @@ test.describe('Tablist', () => {
test('should set aria-disabled on individual tabs when tablist is disabled', async ({ fastPage }) => {
const { element } = fastPage;
- const tabs = element.locator('fluent-tab');
+ const tabs = element.locator(TabTagName);
+
+ await fastPage.setTemplate();
// Initially tabs should not have aria-disabled
await expect(tabs.nth(0)).not.toHaveAttribute('aria-disabled');
@@ -75,6 +80,8 @@ test.describe('Tablist', () => {
test('should have role of `tablist`', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).toHaveAttribute('role', 'tablist');
});
@@ -83,12 +90,16 @@ test.describe('Tablist', () => {
}) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).toHaveJSProperty('orientation', 'horizontal');
});
test('should set an `id` attribute on the active tab when an `id` is provided', async ({ fastPage }) => {
const { element } = fastPage;
- const tabs = element.locator('fluent-tab');
+ const tabs = element.locator(TabTagName);
+
+ await fastPage.setTemplate();
const tabCount = await tabs.count();
@@ -108,7 +119,9 @@ test.describe('Tablist', () => {
fastPage,
}) => {
const { element } = fastPage;
- const tabs = element.locator('fluent-tab');
+ const tabs = element.locator(TabTagName);
+
+ await fastPage.setTemplate();
const tabCount = await tabs.count();
@@ -128,7 +141,9 @@ test.describe('Tablist', () => {
test('should default the first tab as the active index if `activeid` is NOT provided', async ({ fastPage }) => {
const { element } = fastPage;
- const tabs = element.locator('fluent-tab');
+ const tabs = element.locator(TabTagName);
+
+ await fastPage.setTemplate();
await expect(tabs.nth(0)).toHaveAttribute('aria-selected', 'true');
});
@@ -139,7 +154,9 @@ test.describe('Tablist', () => {
fastPage,
}) => {
const { element } = fastPage;
- const tabs = element.locator('fluent-tab');
+ const tabs = element.locator(TabTagName);
+
+ await fastPage.setTemplate();
const secondTab = tabs.nth(1);
@@ -156,7 +173,9 @@ test.describe('Tablist', () => {
fastPage,
}) => {
const { element } = fastPage;
- const tabs = element.locator('fluent-tab');
+ const tabs = element.locator(TabTagName);
+
+ await fastPage.setTemplate();
await expect(tabs.nth(0)).toHaveAttribute('aria-selected', 'true');
@@ -175,9 +194,11 @@ test.describe('Tablist', () => {
test('should set the `appearance` property to match the `appearance` attribute', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const appearance of Object.values(TablistAppearance)) {
await test.step(appearance, async () => {
- await fastPage.setTemplate({ attributes: { appearance } });
+ await fastPage.updateTemplate(element, { attributes: { appearance } });
await expect(element).toHaveJSProperty('appearance', appearance);
@@ -189,9 +210,11 @@ test.describe('Tablist', () => {
test('should set the `size` property to match the `size` attribute', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
for (const size of Object.values(TablistSize)) {
await test.step(size, async () => {
- await fastPage.setTemplate({ attributes: { size } });
+ await fastPage.updateTemplate(element, { attributes: { size } });
await expect(element).toHaveJSProperty('size', size);
@@ -202,13 +225,13 @@ test.describe('Tablist', () => {
test('should not allow selecting a tab that has been disabled after it has been connected', async ({ fastPage }) => {
const { element } = fastPage;
- const tabs = element.locator('fluent-tab');
+ const tabs = element.locator(TabTagName);
await fastPage.setTemplate({
innerHTML: /* html */ `
- Tab one
- Tab two
- Tab three
+ <${TabTagName} id="tab-1">Tab one${TabTagName}>
+ <${TabTagName} id="tab-2">Tab two${TabTagName}>
+ <${TabTagName} id="tab-3">Tab three${TabTagName}>
`,
});
@@ -236,13 +259,13 @@ test.describe('Tablist', () => {
test('should allow selecting tab that has been enabled after it has been connected', async ({ fastPage }) => {
const { element } = fastPage;
- const tabs = element.locator('fluent-tab');
+ const tabs = element.locator(TabTagName);
await fastPage.setTemplate({
innerHTML: /* html */ `
- Tab one
- Tab two
- Tab three
+ <${TabTagName}>Tab one${TabTagName}>
+ <${TabTagName} disabled>Tab two${TabTagName}>
+ <${TabTagName}>Tab three${TabTagName}>
`,
});
@@ -276,13 +299,13 @@ test.describe('Tablist', () => {
test('should keep disabled selected tab focusable until it loses selected state', async ({ fastPage }) => {
const { element, page } = fastPage;
- const tabs = element.locator('fluent-tab');
+ const tabs = element.locator(TabTagName);
await fastPage.setTemplate({
innerHTML: /* html */ `
- Tab one
- Tab two
- Tab three
+ <${TabTagName}>Tab one${TabTagName}>
+ <${TabTagName}>Tab two${TabTagName}>
+ <${TabTagName}>Tab three${TabTagName}>
`,
});
@@ -307,13 +330,13 @@ test.describe('Tablist', () => {
test('should not allow selecting hidden tab using arrow keys', async ({ fastPage }) => {
const { element } = fastPage;
- const tabs = element.locator('fluent-tab');
+ const tabs = element.locator(TabTagName);
await fastPage.setTemplate({
innerHTML: /* html */ `
- Tab one
- Tab two
- Tab three
+ <${TabTagName}>Tab one${TabTagName}>
+ <${TabTagName} hidden>Tab two${TabTagName}>
+ <${TabTagName}>Tab three${TabTagName}>
`,
});
@@ -335,13 +358,13 @@ test.describe('Tablist', () => {
test('should not allow selecting hidden tab by pressing End', async ({ fastPage }) => {
const { element } = fastPage;
- const tabs = element.locator('fluent-tab');
+ const tabs = element.locator(TabTagName);
await fastPage.setTemplate({
innerHTML: /* html */ `
- Tab one
- Tab two
- Tab three
+ <${TabTagName}>Tab one${TabTagName}>
+ <${TabTagName}>Tab two${TabTagName}>
+ <${TabTagName} hidden>Tab three${TabTagName}>
`,
});
@@ -364,11 +387,11 @@ test.describe('Tablist', () => {
test('should associate panel elements with `aria-controls` attributes', async ({ fastPage, page }) => {
const { element } = fastPage;
await fastPage.setTemplate(`
-
- Tab one
- Tab two
- Tab three
-
+ <${tagName}>
+ <${TabTagName} aria-controls="panel1">Tab one${TabTagName}>
+ <${TabTagName} aria-controls="panel2">Tab two${TabTagName}>
+ <${TabTagName} aria-controls="panel3">Tab three${TabTagName}>
+ ${tagName}>
Panel one
Panel two
Panel three
@@ -401,12 +424,12 @@ test.describe('Tablist', () => {
await fastPage.setTemplate({
attributes: { orientation: 'vertical' },
innerHTML: /* html */ `
- Tab one
- TTab two
- Tab three
+ <${TabTagName}>Tab one${TabTagName}>
+ <${TabTagName}>TTab two${TabTagName}>
+ <${TabTagName}>Tab three${TabTagName}>
`,
});
- const tabs = element.locator('fluent-tab');
+ const tabs = element.locator(TabTagName);
await expect(tabs.nth(0)).toHaveAttribute('data-hasIndent');
await expect(tabs.nth(1)).toHaveAttribute('data-hasIndent');
diff --git a/packages/web-components/src/text-input/text-input.spec.ts b/packages/web-components/src/text-input/text-input.spec.ts
index 4ef00687ec7953..f88e019b164bd0 100644
--- a/packages/web-components/src/text-input/text-input.spec.ts
+++ b/packages/web-components/src/text-input/text-input.spec.ts
@@ -1,9 +1,11 @@
import { expect, test } from '../../test/playwright/index.js';
import type { TextInput } from './text-input.js';
-import { ImplicitSubmissionBlockingTypes } from './text-input.options.js';
+import { ImplicitSubmissionBlockingTypes, tagName } from './text-input.options.js';
test.describe('TextInput', () => {
- test.use({ tagName: 'fluent-text-input' });
+ test.use({
+ tagName,
+ });
test('should create with document.createElement()', async ({ page, fastPage }) => {
await fastPage.setTemplate();
@@ -14,9 +16,9 @@ test.describe('TextInput', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-text-input');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -178,6 +180,8 @@ test.describe('TextInput', () => {
test('should have an undefined `value` property when no `value` attribute is set', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).toHaveJSProperty('value', undefined);
});
@@ -194,13 +198,13 @@ test.describe('TextInput', () => {
await fastPage.setTemplate('');
- await page.evaluate(() => {
- const textInput = document.createElement('fluent-text-input') as TextInput;
+ await page.evaluate(tagName => {
+ const textInput = document.createElement(tagName) as TextInput;
textInput.value = 'foo';
document.body.append(textInput);
- });
+ }, tagName);
await expect(element).toHaveJSProperty('value', 'foo');
});
@@ -209,6 +213,8 @@ test.describe('TextInput', () => {
const { element } = fastPage;
const control = element.locator('input');
+ await fastPage.setTemplate();
+
await element.evaluate(node => {
node.setAttribute('value', 'foo');
});
@@ -224,6 +230,8 @@ test.describe('TextInput', () => {
const { element } = fastPage;
const control = element.locator('input');
+ await fastPage.setTemplate();
+
await control.fill('bar');
await element.evaluate(node => {
@@ -337,6 +345,8 @@ test.describe('TextInput', () => {
test('should fire a `change` event when the internal control emits a `change` event', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
const wasChanged = element.evaluate(
node =>
new Promise(resolve => {
@@ -528,7 +538,7 @@ test.describe('TextInput', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -538,6 +548,8 @@ test.describe('TextInput', () => {
test('should set the `form` property to `null` when the element is not in a form', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).toHaveJSProperty('form', null);
});
@@ -548,7 +560,7 @@ test.describe('TextInput', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -562,7 +574,7 @@ test.describe('TextInput', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -578,7 +590,7 @@ test.describe('TextInput', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -599,7 +611,7 @@ test.describe('TextInput', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -620,7 +632,7 @@ test.describe('TextInput', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -641,7 +653,7 @@ test.describe('TextInput', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -663,7 +675,7 @@ test.describe('TextInput', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -678,7 +690,7 @@ test.describe('TextInput', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -696,7 +708,7 @@ test.describe('TextInput', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -748,7 +760,7 @@ test.describe('TextInput', () => {
await fastPage.setTemplate(/* html */ `
`);
@@ -765,6 +777,8 @@ test.describe('TextInput', () => {
test('should change the `value` property when the `current-value` attribute changes', async ({ fastPage, page }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await element.evaluate(node => {
node.setAttribute('current-value', 'foo');
});
@@ -775,6 +789,8 @@ test.describe('TextInput', () => {
test('should change the `value` property when the `currentValue` property changes', async ({ fastPage, page }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await element.evaluate((node: TextInput) => {
node.currentValue = 'foo';
});
@@ -785,6 +801,8 @@ test.describe('TextInput', () => {
test('should set the `current-value` attribute to match the `value` property', async ({ fastPage, page }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).not.toHaveAttribute('current-value');
await element.evaluate((node: TextInput) => {
@@ -797,6 +815,8 @@ test.describe('TextInput', () => {
test('should set the `currentValue` property to match the `value` property', async ({ fastPage, page }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).toHaveJSProperty('currentValue', undefined);
await element.evaluate((node: TextInput) => {
diff --git a/packages/web-components/src/text/text.spec.ts b/packages/web-components/src/text/text.spec.ts
index 1e8567164f29f9..63beb0a5047826 100644
--- a/packages/web-components/src/text/text.spec.ts
+++ b/packages/web-components/src/text/text.spec.ts
@@ -1,8 +1,11 @@
import { expect, test } from '../../test/playwright/index.js';
-import { TextAlign, TextFont, TextSize, TextWeight } from './text.options.js';
+import { tagName, TextAlign, TextFont, TextSize, TextWeight } from './text.options.js';
test.describe('Text Component', () => {
- test.use({ tagName: 'fluent-text' });
+ test.use({
+ tagName,
+ innerHTML: 'Text',
+ });
test('should create with document.createElement()', async ({ page, fastPage }) => {
await fastPage.setTemplate();
@@ -13,9 +16,9 @@ test.describe('Text Component', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-text');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -28,7 +31,7 @@ test.describe('Text Component', () => {
await expect(element).toHaveJSProperty('nowrap', true);
await test.step('should set the `nowrap` property to false when the `nowrap` attribute is removed', async () => {
- await fastPage.setTemplate({ attributes: {} });
+ await element.evaluate(node => node.removeAttribute('nowrap'));
await expect(element).toHaveJSProperty('nowrap', false);
});
@@ -44,7 +47,7 @@ test.describe('Text Component', () => {
await expect(element).toHaveJSProperty('truncate', true);
await test.step('should set the `truncate` property to false when the `truncate` attribute is removed', async () => {
- await fastPage.setTemplate({ attributes: {} });
+ await element.evaluate(node => node.removeAttribute('truncate'));
await expect(element).toHaveJSProperty('truncate', false);
});
@@ -58,7 +61,7 @@ test.describe('Text Component', () => {
await expect(element).toHaveJSProperty('italic', true);
await test.step('should set the `italic` property to false when the `italic` attribute is removed', async () => {
- await fastPage.setTemplate({ attributes: {} });
+ await element.evaluate(node => node.removeAttribute('italic'));
await expect(element).toHaveJSProperty('italic', false);
});
@@ -74,7 +77,7 @@ test.describe('Text Component', () => {
await expect(element).toHaveJSProperty('underline', true);
await test.step('should set the `underline` property to false when the `underline` attribute is removed', async () => {
- await fastPage.setTemplate({ attributes: {} });
+ await element.evaluate(node => node.removeAttribute('underline'));
await expect(element).toHaveJSProperty('underline', false);
});
@@ -90,7 +93,7 @@ test.describe('Text Component', () => {
await expect(element).toHaveJSProperty('strikethrough', true);
await test.step('should set the `strikethrough` property to false when the `strikethrough` attribute is removed', async () => {
- await fastPage.setTemplate({ attributes: {} });
+ await element.evaluate(node => node.removeAttribute('strikethrough'));
await expect(element).toHaveJSProperty('strikethrough', false);
});
diff --git a/packages/web-components/src/textarea/textarea.spec.ts b/packages/web-components/src/textarea/textarea.spec.ts
index 8da1fb69475ece..5d9bff314906f4 100644
--- a/packages/web-components/src/textarea/textarea.spec.ts
+++ b/packages/web-components/src/textarea/textarea.spec.ts
@@ -1,11 +1,12 @@
import { expect, test } from '../../test/playwright/index.js';
-import { TextAreaAppearance, TextAreaResize, TextAreaSize } from './textarea.options.js';
+import { tagName as LabelTagName } from '../label/label.options.js';
import type { TextArea } from './textarea.js';
+import { tagName, TextAreaAppearance, TextAreaResize, TextAreaSize } from './textarea.options.js';
test.describe('TextArea', () => {
test.use({
- tagName: 'fluent-textarea',
- waitFor: ['fluent-label'],
+ tagName,
+ waitFor: [LabelTagName],
});
test('should create with document.createElement()', async ({ page, fastPage }) => {
@@ -17,9 +18,9 @@ test.describe('TextArea', () => {
hasError = true;
});
- await page.evaluate(() => {
- document.createElement('fluent-textarea');
- });
+ await page.evaluate(tagName => {
+ document.createElement(tagName);
+ }, tagName);
expect(hasError).toBe(false);
});
@@ -28,12 +29,16 @@ test.describe('TextArea', () => {
test('should not have a role on element internals', async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).toHaveJSProperty('elementInternals.role', null);
});
test("should always return 'textarea' for the `type` prop", async ({ fastPage }) => {
const { element } = fastPage;
+ await fastPage.setTemplate();
+
await expect(element).toHaveJSProperty('type', 'textarea');
});
@@ -69,8 +74,8 @@ test.describe('TextArea', () => {
await fastPage.setTemplate(/* html */ `
-
-