chore(tabs): adds screenshot tests

PiperOrigin-RevId: 532182408
This commit is contained in:
Material Web Team 2023-05-15 12:00:37 -07:00 committed by Copybara-Service
parent 6116c347e9
commit 2b111bdf47
5 changed files with 49 additions and 25 deletions

View File

@ -15,12 +15,20 @@ import {Tabs} from './lib/tabs.js';
export class TabHarness extends Harness<Tab> {
override async getInteractiveElement() {
await this.element.updateComplete;
return this.element.querySelector<HTMLButtonElement|HTMLLinkElement>(
'.button')!;
return this.element.renderRoot
.querySelector<HTMLButtonElement|HTMLLinkElement>('.button')!;
}
private async completeIndicatorAnimation() {
await this.element.updateComplete;
const animations = this.element.indicator.getAnimations();
for (const animation of animations) {
animation.finish();
}
}
async isIndicatorShowing() {
await this.element.updateComplete;
await this.completeIndicatorAnimation();
const opacity = getComputedStyle(this.element.indicator)['opacity'];
return opacity === '1';
}
@ -30,6 +38,17 @@ export class TabHarness extends Harness<Tab> {
* Test harness for Tabs.
*/
export class TabsHarness extends Harness<Tabs> {
// Note, Tabs interactive element is the interactive element of the
// selected tab.
override async getInteractiveElement() {
await this.element.updateComplete;
const selectedItemHarness =
(this.element.selectedItem as ElementWithHarness<Tab>).harness as
TabHarness ??
new TabHarness(this.element.selectedItem);
return await selectedItemHarness.getInteractiveElement();
}
get harnessedItems() {
// Test access to protected property
// tslint:disable-next-line:no-dict-access-on-struct-type

View File

@ -81,10 +81,6 @@ export class Tab extends LitElement {
@state() private showRipple = false;
// whether or not selection state can be animated; used to avoid initial
// animation and becomes true one task after first update.
private canAnimate = false;
constructor() {
super();
if (!isServer) {
@ -125,13 +121,8 @@ export class Tab extends LitElement {
</button>`;
}
protected override async firstUpdated() {
await new Promise(requestAnimationFrame);
this.canAnimate = true;
}
protected override updated(changed: PropertyValues) {
if (changed.has('selected') && this.shouldAnimate()) {
if (changed.has('selected') && !this.disabled) {
this.animateSelected();
}
}
@ -144,10 +135,6 @@ export class Tab extends LitElement {
dispatchActivationClick(this.button);
};
private shouldAnimate() {
return this.canAnimate && !this.disabled;
}
private readonly getRipple = () => {
this.showRipple = true;
return this.ripple;

View File

@ -232,10 +232,6 @@ export class Tabs extends LitElement {
}
protected override async updated(changed: PropertyValues) {
// if there's no items, they may not be ready, so wait before syncronizing
if (this.items.length === 0) {
await new Promise(requestAnimationFrame);
}
const itemsOrVariantChanged =
changed.has('items') || changed.has('variant');
// sync variant with items.
@ -296,13 +292,20 @@ export class Tabs extends LitElement {
this.requestUpdate();
}
private async itemsUpdateComplete() {
for (const item of this.items) {
await item.updateComplete;
}
return true;
}
// ensures the given item is visible in view; defaults to the selected item
private async scrollItemIntoView(item = this.selectedItem) {
if (!item) {
return;
}
// wait for items to render.
await new Promise(requestAnimationFrame);
await this.itemsUpdateComplete();
const isVertical = this.orientation === 'vertical';
const offset = isVertical ? item.offsetTop : item.offsetLeft;
const extent = isVertical ? item.offsetHeight : item.offsetWidth;
@ -311,8 +314,11 @@ export class Tabs extends LitElement {
const min = offset - this.scrollMargin;
const max = offset + extent - hostExtent + this.scrollMargin;
const to = Math.min(min, Math.max(max, scroll));
const behavior =
// type annotation because `instant` is valid but not included in type.
this.focusedItem !== undefined ? 'smooth' : 'instant' as ScrollBehavior;
this.scrollTo({
behavior: 'smooth',
behavior,
[isVertical ? 'left' : 'top']: 0,
[isVertical ? 'top' : 'left']: to
});

View File

@ -0,0 +1,13 @@
{
"capabilities": {
"goog:chromeOptions": {
"args": ["--window-position=0,0", "--window-size=3400,2215"]
},
"moz:firefoxOptions": {
"args": ["-width=3400","-height=2215"]
}
},
"extension": {
"xvfbResolution": "3400x2215x24"
}
}

View File

@ -24,7 +24,6 @@ $_default: (
'md-sys-shape': md-sys-shape.values(),
'md-sys-state': md-sys-state.values(),
'md-sys-typescale': md-sys-typescale.values(),
'md-comp-divider': md-comp-divider.values(),
);
$supported-tokens: (
@ -242,7 +241,7 @@ $unsupported-tokens: (
// add tokens for divider / label-text
@function _add-missing-tokens($tokens, $deps) {
$divider-tokens: map.get($deps, 'md-comp-divider');
$divider-tokens: md-comp-divider.values();
@each $key, $value in $divider-tokens {
$key: 'divider-#{$key}';
$tokens: map.set($tokens, $key, $value);