diff --git a/packages/web-components/src/avatar/avatar.spec.ts b/packages/web-components/src/avatar/avatar.spec.ts
new file mode 100644
index 0000000000000..5fab067f8ba0d
--- /dev/null
+++ b/packages/web-components/src/avatar/avatar.spec.ts
@@ -0,0 +1,205 @@
+import { expect, test } from '@playwright/test';
+import type { Locator, Page } from '@playwright/test';
+import { fixtureURL } from '../helpers.tests.js';
+import { Avatar } from './avatar.js';
+import { AvatarAppearance, AvatarColor, AvatarSize } from './avatar.options.js';
+
+test.describe('Avatar Component', () => {
+ let page: Page;
+ let element: Locator;
+ let root: Locator;
+
+ test.beforeAll(async ({ browser }) => {
+ page = await browser.newPage();
+
+ element = page.locator('fluent-avatar');
+
+ root = page.locator('#root');
+
+ await page.goto(fixtureURL('components-avatar--avatar'));
+ });
+
+ test.afterAll(async () => {
+ await page.close();
+ });
+
+ const colorAttributes = {
+ neutral: 'neutral',
+ brand: 'brand',
+ colorful: 'colorful',
+ darkRed: 'dark-red',
+ cranberry: 'cranberry',
+ red: 'red',
+ pumpkin: 'pumpkin',
+ peach: 'peach',
+ marigold: 'marigold',
+ gold: 'gold',
+ brass: 'brass',
+ brown: 'brown',
+ forest: 'forest',
+ seafoam: 'seafoam',
+ darkGreen: 'dark-green',
+ lightTeal: 'light-teal',
+ teal: 'teal',
+ steel: 'steel',
+ blue: 'blue',
+ royalBlue: 'royal-blue',
+ cornflower: 'cornflower',
+ navy: 'navy',
+ lavender: 'lavender',
+ purple: 'purple',
+ grape: 'grape',
+ lilac: 'lilac',
+ pink: 'pink',
+ magenta: 'magenta',
+ plum: 'plum',
+ beige: 'beige',
+ mink: 'mink',
+ platinum: 'platinum',
+ anchor: 'anchor',
+ };
+
+ const appearanceAttributes = {
+ ring: 'ring',
+ shadow: 'shadow',
+ ringShadow: 'ring-shadow',
+ };
+
+ const sizeAttributes = {
+ _16: 16,
+ _20: 20,
+ _24: 24,
+ _28: 28,
+ _32: 32,
+ _36: 36,
+ _40: 40,
+ _48: 48,
+ _56: 56,
+ _64: 64,
+ _72: 72,
+ _96: 96,
+ _120: 120,
+ _128: 128,
+ };
+
+ test('should render without crashing', async () => {
+ await page.waitForSelector('fluent-avatar');
+ await expect(element).toBeVisible();
+ });
+
+ test('When no name value is set, should render with custom initials based on the provided initials value', async () => {
+ await root.evaluate(node => {
+ node.innerHTML = /* html */ `
+
+ `;
+ });
+
+ await expect(element).toHaveText('JD');
+ });
+
+ test('When name value is set, should generate initials based on the provided name value', async () => {
+ await root.evaluate(node => {
+ node.innerHTML = /* html */ `
+
+ `;
+ });
+
+ await expect(element).toHaveText('JD');
+ });
+
+ test('When name value and custom initials are set, should prioritize the provided initials', async () => {
+ await root.evaluate(node => {
+ node.innerHTML = /* html */ `
+
+ `;
+ });
+
+ await expect(element).toHaveText('JJ');
+ });
+
+ test('should render correctly in active state', async () => {
+ await element.evaluate((node: Avatar) => {
+ node.active = 'active';
+ });
+
+ await expect(element).toHaveJSProperty('active', 'active');
+ });
+
+ test('should render correctly in inactive state', async () => {
+ await element.evaluate((node: Avatar) => {
+ node.active = 'inactive';
+ });
+
+ await expect(element).toHaveJSProperty('active', 'inactive');
+ });
+
+ test('default color should be neutral', async () => {
+ await expect(element).toHaveAttribute('data-color', `neutral`);
+ });
+
+ test('should default to a specific color when "colorful" is set without name or colorId', async () => {
+ await element.evaluate((node: Avatar) => {
+ node.color = 'colorful';
+ });
+ const generatedColor = await element.evaluate((node: Avatar) => {
+ return node.generateColor();
+ });
+ await expect(element).toHaveAttribute('data-color', `${generatedColor}`);
+ });
+
+ test('should derive the color from the name attribute when set to "colorful"', async () => {
+ await root.evaluate(node => {
+ node.innerHTML = /* html */ `
+
+ `;
+ });
+
+ const generatedColor = await element.evaluate((node: Avatar) => {
+ return node.generateColor();
+ });
+
+ await expect(element).toHaveAttribute('data-color', `${generatedColor}`);
+ });
+
+ test('should prioritize color derivation from colorId over name when set to "colorful"', async () => {
+ await root.evaluate(node => {
+ node.innerHTML = /* html */ `
+
+ `;
+ });
+
+ const generatedColor = await element.evaluate((node: Avatar) => {
+ return node.generateColor();
+ });
+ await expect(element).toHaveAttribute('data-color', `${generatedColor}`);
+ });
+
+ for (const [, value] of Object.entries(colorAttributes)) {
+ test(`should set the color attribute to \`${value}\` on the internal control`, async () => {
+ await element.evaluate((node: Avatar, colorValue: string) => {
+ node.color = colorValue as AvatarColor;
+ }, value as string);
+ await expect(element).toHaveJSProperty('color', `${value}`);
+ await expect(element).toHaveAttribute('color', `${value}`);
+ });
+ }
+ for (const [, value] of Object.entries(sizeAttributes)) {
+ test(`should set the size attribute to \`${value}\` on the internal control`, async () => {
+ await element.evaluate((node: Avatar, sizeValue: number) => {
+ node.size = sizeValue as AvatarSize;
+ }, value as number);
+ await expect(element).toHaveJSProperty('size', value);
+ await expect(element).toHaveAttribute('size', `${value}`);
+ });
+ }
+ for (const [, value] of Object.entries(appearanceAttributes)) {
+ test(`should set and reflect the appearance attribute to \`${value}\` on the internal control`, async () => {
+ await element.evaluate((node: Avatar, appearanceValue: string) => {
+ node.appearance = appearanceValue as AvatarAppearance;
+ }, value as string);
+
+ await expect(element).toHaveJSProperty('appearance', `${value}`);
+ await expect(element).toHaveAttribute('appearance', `${value}`);
+ });
+ }
+});