Skip to content
9 changes: 5 additions & 4 deletions core/src/components/title/test/basic/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

<body>
<ion-app>
<div id="header-wrapper">
<div id="container">
<ion-header>
<ion-toolbar>
<ion-title>Settings</ion-title>
Expand All @@ -38,7 +38,7 @@
<ion-back-button default-href="#"></ion-back-button>
</ion-buttons>
<ion-title>Title</ion-title>
<ion-title class="hide-ios" size="small">Subtitle</ion-title>
<ion-title class="hide-when-centered" size="small">Subtitle</ion-title>
<ion-buttons slot="end">
<ion-button><ion-icon slot="icon-only" name="search"></ion-icon></ion-button>
<ion-button><ion-icon slot="icon-only" name="menu"></ion-icon></ion-button>
Expand Down Expand Up @@ -80,8 +80,9 @@
</ion-app>

<style>
.ios .hide-ios,
.ionic .hide-ios {
/* ios and ionic center the title, so a second title would overlap it */
.ios .hide-when-centered,
.ionic .hide-when-centered {
display: none;
}
</style>
Expand Down
81 changes: 76 additions & 5 deletions core/src/components/title/test/basic/title.e2e.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,85 @@
import { expect } from '@playwright/test';
import { configs, test } from '@utils/test/playwright';

configs({ modes: ['ionic-md', 'md', 'ios'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
configs({ modes: ['ionic-md', 'md', 'ios'] }).forEach(({ title, screenshot, config }) => {
test.describe(title('title: basic'), () => {
test('should not have visual regressions', async ({ page }) => {
await page.goto('/src/components/title/test/basic', config);
const wrapper = page.locator('#header-wrapper');
await page.setContent(
`
<style>
/* ios and ionic center the title, so a second title would overlap it */
.ios .hide-when-centered,
.ionic .hide-when-centered {
display: none;
}
</style>

<div id="container">
<ion-header>
<ion-toolbar>
<ion-title>Settings</ion-title>
</ion-toolbar>
</ion-header>

<ion-header>
<ion-toolbar>
<ion-title>Browse</ion-title>
<ion-buttons slot="end">
<ion-button>Cancel</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>

<ion-header>
<ion-toolbar class="toolbar-title-default">
<ion-buttons slot="start">
<ion-back-button default-href="#"></ion-back-button>
</ion-buttons>
<ion-title>Title</ion-title>
<ion-title class="hide-when-centered" size="small">Subtitle</ion-title>
<ion-buttons slot="end">
<ion-button><ion-icon slot="icon-only" name="search"></ion-icon></ion-button>
<ion-button><ion-icon slot="icon-only" name="menu"></ion-icon></ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>

<ion-header>
<ion-toolbar>
<ion-title size="small">Choose a contact to add to Favorites</ion-title>
</ion-toolbar>
<ion-toolbar>
<ion-title>Contacts</ion-title>
<ion-buttons slot="end">
<ion-button>Cancel</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>

<ion-header>
<ion-toolbar color="secondary">
<ion-title size="small">
Choose multiple contacts to add to your Favorites so this just goes on and on and on
</ion-title>
</ion-toolbar>
<ion-toolbar color="secondary">
<ion-buttons slot="start">
<ion-button>Groups</ion-button>
</ion-buttons>
<ion-title>Contacts</ion-title>
<ion-buttons slot="end">
<ion-button>Cancel</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
</div>
`,
config
);

const container = page.locator('#container');

// only screenshot the headers to avoid unnecessary blank space from ion-content
await expect(wrapper).toHaveScreenshot(screenshot(`title-basic`));
await expect(container).toHaveScreenshot(screenshot(`title-basic`));
});
});
});
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions core/src/components/title/test/color/title.e2e.ts
Comment thread
brandyscarney marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { expect } from '@playwright/test';
import { configs, test } from '@utils/test/playwright';

/**
* This behavior does not vary across directions.
*/
configs({ modes: ['ionic-md', 'md', 'ios'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
test.describe(title('title: color'), () => {
test('should not have visual regressions', async ({ page }) => {
await page.setContent(
`
<ion-header>
<ion-toolbar>
<ion-title color="primary">Primary</ion-title>
</ion-toolbar>
<ion-toolbar>
<ion-title color="tertiary">Tertiary</ion-title>
</ion-toolbar>
<ion-toolbar>
<ion-title color="warning">Warning</ion-title>
</ion-toolbar>
</ion-header>
`,
config
);

const header = page.locator('ion-header');

await expect(header).toHaveScreenshot(screenshot(`title-color`));
});
});
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
89 changes: 89 additions & 0 deletions core/src/components/title/test/title.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { newSpecPage } from '@stencil/core/testing';

import { ToolbarTitle } from '../title';

describe('title: classes', () => {
it('should add the default size class when size is not set', async () => {
const page = await newSpecPage({
components: [ToolbarTitle],
html: `<ion-title>Title</ion-title>`,
});

expect(page.root!.classList.contains('title-default')).toBe(true);
});

it('should add the size class when size is set', async () => {
const page = await newSpecPage({
components: [ToolbarTitle],
html: `<ion-title size="large">Title</ion-title><ion-title size="small">Title</ion-title>`,
});

const [large, small] = Array.from(page.body.querySelectorAll('ion-title'));
expect(large.classList.contains('title-large')).toBe(true);
expect(small.classList.contains('title-small')).toBe(true);
});

it('should add the color classes when color is set', async () => {
const page = await newSpecPage({
components: [ToolbarTitle],
html: `<ion-title color="primary">Title</ion-title>`,
});

expect(page.root!.classList.contains('ion-color')).toBe(true);
expect(page.root!.classList.contains('ion-color-primary')).toBe(true);
});

it('should add the rtl class when the document is rtl', async () => {
const page = await newSpecPage({
components: [ToolbarTitle],
html: `<ion-title>Title</ion-title>`,
direction: 'rtl',
});

expect(page.root!.classList.contains('title-rtl')).toBe(true);
});

/**
* The iOS collapsing header and page transition look up this
* element and measure it, so it must keep its class.
*/
it('should render the inner title element', async () => {
const page = await newSpecPage({
components: [ToolbarTitle],
html: `<ion-title>Title</ion-title>`,
});

expect(page.root!.shadowRoot!.querySelector('.toolbar-title')).not.toBeNull();
});
});

describe('title: style event', () => {
Comment thread
brandyscarney marked this conversation as resolved.
it('should emit the size class when it first connects', async () => {
const page = await newSpecPage({
components: [ToolbarTitle],
html: '',
});

const ionStyle = jest.fn();
page.body.addEventListener('ionStyle', (ev: Event) => ionStyle((ev as CustomEvent).detail));

await page.setContent(`<ion-title size="large">Title</ion-title>`);

expect(ionStyle).toHaveBeenCalledWith({ 'title-large': true });
});

it('should emit the size class when size changes', async () => {
const page = await newSpecPage({
components: [ToolbarTitle],
html: `<ion-title>Title</ion-title>`,
});

const ionStyle = jest.fn();
page.root!.addEventListener('ionStyle', (ev: Event) => ionStyle((ev as CustomEvent).detail));

page.root!.setAttribute('size', 'large');
await page.waitForChanges();

expect(ionStyle).toHaveBeenCalledWith({ 'title-large': true });
});
});
Loading