feat(steps): add types
This commit is contained in:
parent
66c5f2cd36
commit
7d4b6d32db
6 changed files with 176 additions and 94 deletions
5
.changeset/great-suits-poke.md
Normal file
5
.changeset/great-suits-poke.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@lion/steps': minor
|
||||
---
|
||||
|
||||
Add types for steps package.
|
||||
5
.changeset/seven-lizards-explain.md
Normal file
5
.changeset/seven-lizards-explain.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@lion/steps': minor
|
||||
---
|
||||
|
||||
Add types for steps package.
|
||||
|
|
@ -1,5 +1,9 @@
|
|||
import { css, html, LitElement } from '@lion/core';
|
||||
|
||||
/**
|
||||
* @typedef {import('./LionSteps').LionSteps} LionSteps
|
||||
*/
|
||||
|
||||
/**
|
||||
* `LionStep` is one of many in a LionSteps Controller
|
||||
*
|
||||
|
|
@ -8,24 +12,6 @@ import { css, html, LitElement } from '@lion/core';
|
|||
*/
|
||||
export class LionStep extends LitElement {
|
||||
static get properties() {
|
||||
/**
|
||||
* Fired when the step is entered.
|
||||
*
|
||||
* @event enter
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired when the step is left.
|
||||
*
|
||||
* @event left
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired when the step is skipped.
|
||||
*
|
||||
* @event skipped
|
||||
*/
|
||||
|
||||
return {
|
||||
/**
|
||||
* Step status, one of: "untouched", "entered", "left", "skipped".
|
||||
|
|
@ -39,13 +25,14 @@ export class LionStep extends LitElement {
|
|||
* Takes lion-steps data as a first argument `myConditionFunc(data)`.
|
||||
*/
|
||||
condition: {
|
||||
type: Function,
|
||||
attribute: false,
|
||||
},
|
||||
/**
|
||||
* Allows to invert condition function result.
|
||||
*/
|
||||
invertCondition: {
|
||||
type: Boolean,
|
||||
reflect: true,
|
||||
attribute: 'invert-condition',
|
||||
},
|
||||
/**
|
||||
|
|
@ -55,6 +42,7 @@ export class LionStep extends LitElement {
|
|||
*/
|
||||
forwardOnly: {
|
||||
type: Boolean,
|
||||
reflect: true,
|
||||
attribute: 'forward-only',
|
||||
},
|
||||
/**
|
||||
|
|
@ -63,6 +51,7 @@ export class LionStep extends LitElement {
|
|||
*/
|
||||
initialStep: {
|
||||
type: Boolean,
|
||||
reflect: true,
|
||||
attribute: 'initial-step',
|
||||
},
|
||||
};
|
||||
|
|
@ -71,7 +60,8 @@ export class LionStep extends LitElement {
|
|||
constructor() {
|
||||
super();
|
||||
this.status = 'untouched';
|
||||
this.condition = () => true;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
this.condition = /** @param {Object} [data] */ data => true;
|
||||
this.invertCondition = false;
|
||||
this.forwardOnly = false;
|
||||
this.initialStep = false;
|
||||
|
|
@ -99,9 +89,10 @@ export class LionStep extends LitElement {
|
|||
return html`<slot></slot>`;
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
super.firstUpdated();
|
||||
this.controller = this.parentNode;
|
||||
/** @param {import('lit-element').PropertyValues } changedProperties */
|
||||
firstUpdated(changedProperties) {
|
||||
super.firstUpdated(changedProperties);
|
||||
this.controller = /** @type {LionSteps} */ (this.parentNode);
|
||||
}
|
||||
|
||||
enter() {
|
||||
|
|
@ -119,6 +110,7 @@ export class LionStep extends LitElement {
|
|||
this.dispatchEvent(new CustomEvent('skip', { bubbles: true, composed: true }));
|
||||
}
|
||||
|
||||
/** @param {Object} [data] */
|
||||
passesCondition(data) {
|
||||
const result = this.condition(data);
|
||||
return this.invertCondition ? !result : result;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
import { css, html, LitElement } from '@lion/core';
|
||||
|
||||
/**
|
||||
* @typedef {import('./LionStep.js').LionStep} LionStep
|
||||
*/
|
||||
|
||||
/**
|
||||
* `LionSteps` is a controller for a multi step system.
|
||||
*
|
||||
|
|
@ -7,6 +11,20 @@ import { css, html, LitElement } from '@lion/core';
|
|||
* @extends {LitElement}
|
||||
*/
|
||||
export class LionSteps extends LitElement {
|
||||
static get styles() {
|
||||
return [
|
||||
css`
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
|
||||
:host([hidden]) {
|
||||
display: none;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
static get properties() {
|
||||
/**
|
||||
* Fired when a transition between steps happens.
|
||||
|
|
@ -31,43 +49,19 @@ export class LionSteps extends LitElement {
|
|||
};
|
||||
}
|
||||
|
||||
updated(changedProperties) {
|
||||
super.updated(changedProperties);
|
||||
if (changedProperties.has('current')) {
|
||||
this._onCurrentChanged(
|
||||
{ current: this.current },
|
||||
{ current: changedProperties.get('current') },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
/** @type {{[key: string]: ?}} */
|
||||
this.data = {};
|
||||
this._internalCurrentSync = true; // necessary for preventing side effects on initialization
|
||||
/** @type {number} */
|
||||
this.current = 0;
|
||||
this._max = 0;
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return [
|
||||
css`
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
|
||||
:host([hidden]) {
|
||||
display: none;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`<slot></slot>`;
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
super.firstUpdated();
|
||||
/** @param {import('lit-element').PropertyValues } changedProperties */
|
||||
firstUpdated(changedProperties) {
|
||||
super.firstUpdated(changedProperties);
|
||||
this._max = this.steps.length - 1;
|
||||
|
||||
let hasInitial = false;
|
||||
|
|
@ -82,6 +76,21 @@ export class LionSteps extends LitElement {
|
|||
}
|
||||
}
|
||||
|
||||
/** @param {import('lit-element').PropertyValues } changedProperties */
|
||||
updated(changedProperties) {
|
||||
super.updated(changedProperties);
|
||||
if (changedProperties.has('current')) {
|
||||
this._onCurrentChanged(
|
||||
{ current: this.current },
|
||||
{ current: /** @type {number} */ (changedProperties.get('current')) },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`<slot></slot>`;
|
||||
}
|
||||
|
||||
next() {
|
||||
this._goTo(this.current + 1, this.current);
|
||||
}
|
||||
|
|
@ -91,10 +100,18 @@ export class LionSteps extends LitElement {
|
|||
}
|
||||
|
||||
get steps() {
|
||||
const defaultSlot = this.shadowRoot.querySelector('slot:not([name])');
|
||||
return defaultSlot.assignedNodes().filter(node => node.nodeType === Node.ELEMENT_NODE);
|
||||
const defaultSlot = /** @type {HTMLSlotElement} */ (this.shadowRoot?.querySelector(
|
||||
'slot:not([name])',
|
||||
));
|
||||
return /** @type {LionStep[]} */ (defaultSlot.assignedNodes()).filter(
|
||||
node => node.nodeType === Node.ELEMENT_NODE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} newCurrent
|
||||
* @param {number} oldCurrent
|
||||
*/
|
||||
_goTo(newCurrent, oldCurrent) {
|
||||
if (newCurrent < 0 || newCurrent > this._max) {
|
||||
throw new Error(`There is no step at index ${newCurrent}.`);
|
||||
|
|
@ -119,6 +136,10 @@ export class LionSteps extends LitElement {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} newCurrent
|
||||
* @param {number} oldCurrent
|
||||
*/
|
||||
_changeStep(newCurrent, oldCurrent) {
|
||||
const oldStepElement = this.steps[oldCurrent];
|
||||
const newStepElement = this.steps[newCurrent];
|
||||
|
|
@ -137,6 +158,10 @@ export class LionSteps extends LitElement {
|
|||
this._dispatchTransitionEvent(fromStep, toStep);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{number: number, element: LionStep}} fromStep
|
||||
* @param {{number: number, element: LionStep}} toStep
|
||||
*/
|
||||
_dispatchTransitionEvent(fromStep, toStep) {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent('transition', {
|
||||
|
|
@ -147,6 +172,10 @@ export class LionSteps extends LitElement {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{current: number}} newValues
|
||||
* @param {{current: number}} oldValues
|
||||
*/
|
||||
_onCurrentChanged(newValues, oldValues) {
|
||||
if (this._internalCurrentSync) {
|
||||
this._internalCurrentSync = false;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@ import { expect, fixture, html, oneEvent } from '@open-wc/testing';
|
|||
|
||||
import '../lion-step.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../src/LionStep').LionStep} LionStep
|
||||
*/
|
||||
|
||||
describe('lion-step', () => {
|
||||
it('has a condition which allows it to become active (condition is true by default)', async () => {
|
||||
const el = await fixture(html`
|
||||
|
|
@ -9,8 +13,8 @@ describe('lion-step', () => {
|
|||
<lion-step>Step 1</lion-step>
|
||||
</fake-lion-steps>
|
||||
`);
|
||||
expect(el.children[0].condition()).to.equal(true);
|
||||
expect(el.children[0].passesCondition()).to.equal(true);
|
||||
expect(/** @type {LionStep} */ (el.children[0]).condition()).to.equal(true);
|
||||
expect(/** @type {LionStep} */ (el.children[0]).passesCondition()).to.equal(true);
|
||||
});
|
||||
|
||||
it('does not invert condition by default', async () => {
|
||||
|
|
@ -19,8 +23,8 @@ describe('lion-step', () => {
|
|||
<lion-step>Step 1</lion-step>
|
||||
</fake-lion-steps>
|
||||
`);
|
||||
expect(el.children[0].invertCondition).to.equal(false);
|
||||
expect(el.children[0].passesCondition()).to.equal(true);
|
||||
expect(/** @type {LionStep} */ (el.children[0]).invertCondition).to.equal(false);
|
||||
expect(/** @type {LionStep} */ (el.children[0]).passesCondition()).to.equal(true);
|
||||
});
|
||||
|
||||
it('can invert its condition', async () => {
|
||||
|
|
@ -29,10 +33,10 @@ describe('lion-step', () => {
|
|||
<lion-step>Step 1</lion-step>
|
||||
</fake-lion-steps>
|
||||
`);
|
||||
el.children[0].condition = () => true;
|
||||
el.children[0].invertCondition = true;
|
||||
expect(el.children[0].condition()).to.equal(true);
|
||||
expect(el.children[0].passesCondition()).to.equal(false);
|
||||
/** @type {LionStep} */ (el.children[0]).condition = () => true;
|
||||
/** @type {LionStep} */ (el.children[0]).invertCondition = true;
|
||||
expect(/** @type {LionStep} */ (el.children[0]).condition()).to.equal(true);
|
||||
expect(/** @type {LionStep} */ (el.children[0]).passesCondition()).to.equal(false);
|
||||
});
|
||||
|
||||
it('has "untouched" status by default', async () => {
|
||||
|
|
@ -41,7 +45,7 @@ describe('lion-step', () => {
|
|||
<lion-step>Step 1</lion-step>
|
||||
</fake-lion-steps>
|
||||
`);
|
||||
expect(el.children[0].status).to.equal('untouched');
|
||||
expect(/** @type {LionStep} */ (el.children[0]).status).to.equal('untouched');
|
||||
});
|
||||
|
||||
it('is hidden when attribute hidden is true', async () => {
|
||||
|
|
@ -61,7 +65,7 @@ describe('lion-step', () => {
|
|||
<lion-step>Step 1</lion-step>
|
||||
</fake-lion-steps>
|
||||
`);
|
||||
expect(el.children[0].controller).to.equal(el);
|
||||
expect(/** @type {LionStep} */ (el.children[0]).controller).to.equal(el);
|
||||
});
|
||||
|
||||
describe('navigation', () => {
|
||||
|
|
@ -71,9 +75,9 @@ describe('lion-step', () => {
|
|||
<lion-step>Step 1</lion-step>
|
||||
</fake-lion-steps>
|
||||
`);
|
||||
setTimeout(() => el.children[0].enter(), 0);
|
||||
setTimeout(() => /** @type {LionStep} */ (el.children[0]).enter(), 0);
|
||||
await oneEvent(el.children[0], 'enter');
|
||||
expect(el.children[0].status).to.equal('entered');
|
||||
expect(/** @type {LionStep} */ (el.children[0]).status).to.equal('entered');
|
||||
});
|
||||
|
||||
it('can be left', async () => {
|
||||
|
|
@ -82,9 +86,9 @@ describe('lion-step', () => {
|
|||
<lion-step>Step 1</lion-step>
|
||||
</fake-lion-steps>
|
||||
`);
|
||||
setTimeout(() => el.children[0].leave(), 0);
|
||||
setTimeout(() => /** @type {LionStep} */ (el.children[0]).leave(), 0);
|
||||
await oneEvent(el.children[0], 'leave');
|
||||
expect(el.children[0].status).to.equal('left');
|
||||
expect(/** @type {LionStep} */ (el.children[0]).status).to.equal('left');
|
||||
});
|
||||
|
||||
it('can be skipped', async () => {
|
||||
|
|
@ -93,9 +97,9 @@ describe('lion-step', () => {
|
|||
<lion-step>Step 1</lion-step>
|
||||
</fake-lion-steps>
|
||||
`);
|
||||
setTimeout(() => el.children[0].skip(), 0);
|
||||
setTimeout(() => /** @type {LionStep} */ (el.children[0]).skip(), 0);
|
||||
await oneEvent(el.children[0], 'skip');
|
||||
expect(el.children[0].status).to.equal('skipped');
|
||||
expect(/** @type {LionStep} */ (el.children[0]).status).to.equal('skipped');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,22 +1,40 @@
|
|||
import { expect, fixture, html, oneEvent } from '@open-wc/testing';
|
||||
import { expect, fixture as _fixture, html, oneEvent } from '@open-wc/testing';
|
||||
import sinon from 'sinon';
|
||||
import '../lion-step.js';
|
||||
import '../lion-steps.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../src/LionSteps').LionSteps} LionSteps
|
||||
* @typedef {import('../src/LionStep').LionStep} LionStep
|
||||
* @typedef {import('lit-html').TemplateResult} TemplateResult
|
||||
* @typedef {{[key: string]: ?}} UnknownData
|
||||
*/
|
||||
|
||||
const fixture = /** @type {(arg: TemplateResult) => Promise<LionSteps>} */ (_fixture);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {LionSteps} steps
|
||||
* @param {Object} expected
|
||||
* @param {string} expected.transitions
|
||||
* @param {string} expected.statuses
|
||||
*/
|
||||
async function checkWorkflow(steps, expected) {
|
||||
return new Promise(resolve => {
|
||||
/** @type {number[]} */
|
||||
const transitions = [];
|
||||
steps.addEventListener('transition', event => {
|
||||
const _event = /** @type {CustomEvent} */ (event);
|
||||
if (!transitions.length) {
|
||||
transitions.push(event.detail.fromStep.number);
|
||||
transitions.push(_event.detail.fromStep.number);
|
||||
}
|
||||
transitions.push(event.detail.toStep.number);
|
||||
transitions.push(_event.detail.toStep.number);
|
||||
});
|
||||
setTimeout(() => {
|
||||
// allow time for other transitions to happen if any
|
||||
const transitionsString = transitions.join(' => ');
|
||||
expect(transitionsString).to.equal(expected.transitions, 'transition flow is different');
|
||||
const statusesString = Array.from(steps.children)
|
||||
const statusesString = /** @type {LionStep[]} */ (Array.from(steps.children))
|
||||
.map(step => step.status)
|
||||
.join(' ');
|
||||
expect(statusesString).to.equal(expected.statuses, 'steps statuses are different');
|
||||
|
|
@ -60,7 +78,7 @@ describe('lion-steps', () => {
|
|||
</lion-steps>
|
||||
`);
|
||||
expect(el.current).to.equal(0);
|
||||
expect(el.children[0].status).to.equal('entered');
|
||||
expect(/** @type {LionStep} */ (el.children[0]).status).to.equal('entered');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -133,9 +151,13 @@ describe('lion-steps', () => {
|
|||
const el = await fixture(html`
|
||||
<lion-steps .data=${{ age: 25 }}>
|
||||
<lion-step initial-step>Step 0</lion-step>
|
||||
<lion-step .condition=${data => data.age < 18}>Step 1</lion-step>
|
||||
<lion-step .condition=${/** @param {UnknownData} data */ data => data.age < 18}
|
||||
>Step 1</lion-step
|
||||
>
|
||||
<lion-step>Step 2</lion-step>
|
||||
<lion-step .condition=${data => data.age < 22}>Step 3</lion-step>
|
||||
<lion-step .condition=${/** @param {UnknownData} data */ data => data.age < 22}
|
||||
>Step 3</lion-step
|
||||
>
|
||||
<lion-step>Step 4</lion-step>
|
||||
</lion-steps>
|
||||
`);
|
||||
|
|
@ -170,8 +192,8 @@ describe('lion-steps', () => {
|
|||
describe('events', () => {
|
||||
it('will fire lion-step @leave event before changing .current', async () => {
|
||||
let currentInLeaveEvent;
|
||||
const onLeave = ev => {
|
||||
currentInLeaveEvent = ev.target.controller.current;
|
||||
const onLeave = /** @param {Event} ev */ ev => {
|
||||
currentInLeaveEvent = /** @type {LionStep} */ (ev.target).controller?.current;
|
||||
};
|
||||
const el = await fixture(html`
|
||||
<lion-steps>
|
||||
|
|
@ -186,8 +208,8 @@ describe('lion-steps', () => {
|
|||
|
||||
it('will fire lion-step @enter event after changing .current', async () => {
|
||||
let currentInEnterEvent;
|
||||
const onEnter = ev => {
|
||||
currentInEnterEvent = ev.target.controller.current;
|
||||
const onEnter = /** @param {Event} ev */ ev => {
|
||||
currentInEnterEvent = /** @type {LionStep} */ (ev.target).controller?.current;
|
||||
};
|
||||
const el = await fixture(html`
|
||||
<lion-steps>
|
||||
|
|
@ -245,9 +267,16 @@ describe('lion-steps', () => {
|
|||
const el = await fixture(html`
|
||||
<lion-steps .data=${{ age: 25 }}>
|
||||
<lion-step initial-step>Step 0</lion-step>
|
||||
<lion-step .condition=${data => data.age < 18}>Step 1</lion-step>
|
||||
<lion-step .condition=${data => data.age >= 18 && data.age < 21}>Step 2</lion-step>
|
||||
<lion-step .condition=${data => data.age >= 21}>Step 3</lion-step>
|
||||
<lion-step .condition=${/** @param {UnknownData} data */ data => data.age < 18}
|
||||
>Step 1</lion-step
|
||||
>
|
||||
<lion-step
|
||||
.condition=${/** @param {UnknownData} data */ data => data.age >= 18 && data.age < 21}
|
||||
>Step 2</lion-step
|
||||
>
|
||||
<lion-step .condition=${/** @param {UnknownData} data */ data => data.age >= 21}
|
||||
>Step 3</lion-step
|
||||
>
|
||||
<lion-step>Step 4</lion-step>
|
||||
</lion-steps>
|
||||
`);
|
||||
|
|
@ -264,9 +293,16 @@ describe('lion-steps', () => {
|
|||
const el = await fixture(html`
|
||||
<lion-steps .data=${{ age: 19 }}>
|
||||
<lion-step initial-step>Step 0</lion-step>
|
||||
<lion-step .condition=${data => data.age < 18}>Step 1</lion-step>
|
||||
<lion-step .condition=${data => data.age >= 18 && data.age < 21}>Step 2</lion-step>
|
||||
<lion-step .condition=${data => data.age >= 21}>Step 3</lion-step>
|
||||
<lion-step .condition=${/** @param {UnknownData} data */ data => data.age < 18}
|
||||
>Step 1</lion-step
|
||||
>
|
||||
<lion-step
|
||||
.condition=${/** @param {UnknownData} data */ data => data.age >= 18 && data.age < 21}
|
||||
>Step 2</lion-step
|
||||
>
|
||||
<lion-step .condition=${/** @param {UnknownData} data */ data => data.age >= 21}
|
||||
>Step 3</lion-step
|
||||
>
|
||||
<lion-step>Step 4</lion-step>
|
||||
</lion-steps>
|
||||
`);
|
||||
|
|
@ -285,9 +321,16 @@ describe('lion-steps', () => {
|
|||
const el = await fixture(html`
|
||||
<lion-steps .data=${{ age: 15 }}>
|
||||
<lion-step initial-step>Step 0</lion-step>
|
||||
<lion-step .condition=${data => data.age < 18}>Step 1</lion-step>
|
||||
<lion-step .condition=${data => data.age >= 18 && data.age < 21}>Step 2</lion-step>
|
||||
<lion-step .condition=${data => data.age >= 21}>Step 3</lion-step>
|
||||
<lion-step .condition=${/** @param {UnknownData} data */ data => data.age < 18}
|
||||
>Step 1</lion-step
|
||||
>
|
||||
<lion-step
|
||||
.condition=${/** @param {UnknownData} data */ data => data.age >= 18 && data.age < 21}
|
||||
>Step 2</lion-step
|
||||
>
|
||||
<lion-step .condition=${/** @param {UnknownData} data */ data => data.age >= 21}
|
||||
>Step 3</lion-step
|
||||
>
|
||||
<lion-step>Step 4</lion-step>
|
||||
</lion-steps>
|
||||
`);
|
||||
|
|
@ -309,7 +352,11 @@ describe('lion-steps', () => {
|
|||
const el = await fixture(html`
|
||||
<lion-steps .data=${{}}>
|
||||
<lion-step initial-step>Step 0</lion-step>
|
||||
<lion-step .condition=${data => data.age < 18} invert-condition>Step 1</lion-step>
|
||||
<lion-step
|
||||
.condition=${/** @param {UnknownData} data */ data => data.age < 18}
|
||||
invert-condition
|
||||
>Step 1</lion-step
|
||||
>
|
||||
<lion-step>Step 2</lion-step>
|
||||
</lion-steps>
|
||||
`);
|
||||
|
|
@ -332,7 +379,7 @@ describe('lion-steps', () => {
|
|||
});
|
||||
|
||||
it('behaves like "if/else" in case both condition and inverted condition are present', async () => {
|
||||
const condition = data => data.age < 18;
|
||||
const condition = /** @param {UnknownData} data */ data => data.age < 18;
|
||||
const el = await fixture(html`
|
||||
<lion-steps .data=${{}}>
|
||||
<lion-step initial-step>Step 0</lion-step>
|
||||
|
|
@ -411,7 +458,7 @@ describe('lion-steps', () => {
|
|||
el.next();
|
||||
el.previous();
|
||||
|
||||
expect(el.children[1].status).to.equal('left');
|
||||
expect(/** @type {LionStep} */ (el.children[1]).status).to.equal('left');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue