Skip to content

Commit

Permalink
chore(tabs): adds screenshot tests
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 532182408
  • Loading branch information
material-web-copybara authored and copybara-github committed May 15, 2023
1 parent 6116c34 commit 2b111bd
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 25 deletions.
25 changes: 22 additions & 3 deletions tabs/harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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')!;
}

async isIndicatorShowing() {
private async completeIndicatorAnimation() {
await this.element.updateComplete;
const animations = this.element.indicator.getAnimations();
for (const animation of animations) {
animation.finish();
}
}

async isIndicatorShowing() {
await this.completeIndicatorAnimation();
const opacity = getComputedStyle(this.element.indicator)['opacity'];
return opacity === '1';
}
Expand All @@ -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
Expand Down
15 changes: 1 addition & 14 deletions tabs/lib/tab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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();
}
}
Expand All @@ -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;
Expand Down
18 changes: 12 additions & 6 deletions tabs/lib/tabs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand All @@ -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
});
Expand Down
13 changes: 13 additions & 0 deletions tabs/test/window_size.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
3 changes: 1 addition & 2 deletions tokens/_md-comp-tab.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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: (
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 2b111bd

Please sign in to comment.