mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
fix flaky tests, fix menu
This commit is contained in:
2
core/src/components.d.ts
vendored
2
core/src/components.d.ts
vendored
@@ -1427,7 +1427,7 @@ export namespace Components {
|
||||
* @param name The name of the animation to register.
|
||||
* @param animation The animation function to register.
|
||||
*/
|
||||
'registerAnimation': (name: string, animation: ((menu: MenuI) => IonicAnimation) | AnimationBuilder) => Promise<void>;
|
||||
'registerAnimation': (name: string, animation: AnimationBuilder | ((menu: MenuI) => IonicAnimation)) => Promise<void>;
|
||||
/**
|
||||
* Enable or disable the ability to swipe open the menu.
|
||||
* @param enable If `true`, the menu swipe gesture should be enabled.
|
||||
|
||||
@@ -314,10 +314,11 @@ export class Menu implements ComponentInterface, MenuI {
|
||||
private async startAnimation(shouldOpen: boolean, animated: boolean): Promise<void> {
|
||||
const isReversed = !shouldOpen;
|
||||
|
||||
console.log('play', isReversed);
|
||||
const ani = this.animation!
|
||||
.fill('both')
|
||||
.direction((isReversed) ? 'reverse' : 'normal')
|
||||
.easing((isReversed) ? 'cubic-bezier(0.4, 0.0, 0.6, 1)' : 'cubic-bezier(0.0, 0.0, 0.2, 1)');
|
||||
.easing((isReversed) ? 'cubic-bezier(0.4, 0.0, 0.6, 1)' : 'cubic-bezier(0.0, 0.0, 0.2, 1)')
|
||||
.update(true);
|
||||
|
||||
if (animated) {
|
||||
await ani.playAsync();
|
||||
|
||||
@@ -30,6 +30,7 @@ export interface Animation {
|
||||
easing(easing: string): Animation;
|
||||
delay(delay: number): Animation;
|
||||
parent(animation: Animation): Animation;
|
||||
update(deep: boolean): Animation;
|
||||
|
||||
getKeyframes(): any[];
|
||||
getDirection(): AnimationDirection | undefined;
|
||||
|
||||
@@ -35,6 +35,7 @@ export const createAnimation = () => {
|
||||
let shouldForceSyncPlayback = false;
|
||||
let shouldForceReverseDirection = false;
|
||||
let willComplete = true;
|
||||
let shouldCalculateNumAnimations = true;
|
||||
let ani: Animation;
|
||||
|
||||
/**
|
||||
@@ -534,6 +535,8 @@ export const createAnimation = () => {
|
||||
onFinishCallbacks.forEach(callback => {
|
||||
callback(didComplete, ani);
|
||||
});
|
||||
|
||||
shouldCalculateNumAnimations = true;
|
||||
};
|
||||
|
||||
const animationFinish = () => {
|
||||
@@ -605,13 +608,12 @@ export const createAnimation = () => {
|
||||
animationFinish();
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const initializeAnimation = () => {
|
||||
beforeAnimation();
|
||||
|
||||
numAnimationsRunning = childAnimations.length + 1;
|
||||
|
||||
if (getKeyframes().length > 0) {
|
||||
if (supportsWebAnimations) {
|
||||
initializeWebAnimation();
|
||||
@@ -682,12 +684,23 @@ export const createAnimation = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const updateAnimation = () => {
|
||||
/**
|
||||
* Updates any existing animations.
|
||||
*/
|
||||
const update = (deep = false) => {
|
||||
if (deep) {
|
||||
childAnimations.forEach(animation => {
|
||||
animation.update(deep);
|
||||
});
|
||||
}
|
||||
|
||||
if (supportsWebAnimations) {
|
||||
updateWebAnimation();
|
||||
} else {
|
||||
updateCSSAnimation();
|
||||
}
|
||||
|
||||
return ani;
|
||||
};
|
||||
|
||||
const progressStart = (forceLinearEasing = false) => {
|
||||
@@ -713,7 +726,7 @@ export const createAnimation = () => {
|
||||
if (!shouldComplete) {
|
||||
shouldForceReverseDirection = true;
|
||||
onFinish(() => { willComplete = true; shouldForceReverseDirection = false; });
|
||||
updateAnimation();
|
||||
update();
|
||||
progressStep(1 - step);
|
||||
}
|
||||
|
||||
@@ -783,6 +796,11 @@ export const createAnimation = () => {
|
||||
initializeAnimation();
|
||||
}
|
||||
|
||||
if (shouldCalculateNumAnimations) {
|
||||
numAnimationsRunning = childAnimations.length + 1;
|
||||
shouldCalculateNumAnimations = false;
|
||||
}
|
||||
|
||||
childAnimations.forEach(animation => {
|
||||
animation.play();
|
||||
});
|
||||
@@ -890,6 +908,7 @@ export const createAnimation = () => {
|
||||
keyframes,
|
||||
addAnimation,
|
||||
addElement,
|
||||
update,
|
||||
fill,
|
||||
direction,
|
||||
iterations,
|
||||
|
||||
@@ -1,25 +1,72 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
import { listenForEvent, waitForFunctionTestContext } from '../../../test/utils';
|
||||
|
||||
const navChanged = () => new Promise(resolve => window.addEventListener('ionRouteDidChange', resolve));
|
||||
const ROUTE_CHANGED = 'onRouteChanged';
|
||||
|
||||
test('animation:backwards-compatibility animationbuilder', async () => {
|
||||
const page = await newE2EPage({ url: '/src/utils/animation/test/animationbuilder?ionic:_testing=true' });
|
||||
const page = await newE2EPage({ url: '/src/utils/animation/test/animationbuilder?ionic:_testing=true&_forceAnimationBuilder=true' });
|
||||
const screenshotCompares = [];
|
||||
|
||||
const body = await page.$('body');
|
||||
await listenForEvent(page, 'ionRouteDidChange', body, ROUTE_CHANGED);
|
||||
const routeChangedCount: any = { count: 0 };
|
||||
await page.exposeFunction(ROUTE_CHANGED, () => {
|
||||
routeChangedCount.count += 1;
|
||||
});
|
||||
|
||||
screenshotCompares.push(await page.compareScreenshot());
|
||||
|
||||
page.click('page-root ion-button.next');
|
||||
await page.waitFor(navChanged);
|
||||
await waitForNavChange(page, routeChangedCount);
|
||||
page.click('page-one ion-button.next');
|
||||
await page.waitFor(navChanged);
|
||||
await waitForNavChange(page, routeChangedCount);
|
||||
page.click('page-two ion-button.next');
|
||||
await page.waitFor(navChanged);
|
||||
await waitForNavChange(page, routeChangedCount);
|
||||
page.click('page-three ion-back-button');
|
||||
await page.waitFor(navChanged);
|
||||
await waitForNavChange(page, routeChangedCount);
|
||||
page.click('page-two ion-back-button');
|
||||
await page.waitFor(navChanged);
|
||||
await waitForNavChange(page, routeChangedCount);
|
||||
page.click('page-one ion-back-button');
|
||||
await page.waitFor(navChanged);
|
||||
await waitForNavChange(page, routeChangedCount);
|
||||
|
||||
screenshotCompares.push(await page.compareScreenshot());
|
||||
});
|
||||
|
||||
test('animation:backwards-compatibility animation', async () => {
|
||||
const page = await newE2EPage({ url: '/src/utils/animation/test/animationbuilder?ionic:_testing=true' });
|
||||
const screenshotCompares = [];
|
||||
|
||||
const body = await page.$('body');
|
||||
await listenForEvent(page, 'ionRouteDidChange', body, ROUTE_CHANGED);
|
||||
const routeChangedCount: any = { count: 0 };
|
||||
await page.exposeFunction(ROUTE_CHANGED, () => {
|
||||
routeChangedCount.count += 1;
|
||||
});
|
||||
|
||||
screenshotCompares.push(await page.compareScreenshot());
|
||||
|
||||
page.click('page-root ion-button.next');
|
||||
await waitForNavChange(page, routeChangedCount);
|
||||
page.click('page-one ion-button.next');
|
||||
await waitForNavChange(page, routeChangedCount);
|
||||
page.click('page-two ion-button.next');
|
||||
await waitForNavChange(page, routeChangedCount);
|
||||
page.click('page-three ion-back-button');
|
||||
await waitForNavChange(page, routeChangedCount);
|
||||
page.click('page-two ion-back-button');
|
||||
await waitForNavChange(page, routeChangedCount);
|
||||
page.click('page-one ion-back-button');
|
||||
await waitForNavChange(page, routeChangedCount);
|
||||
|
||||
screenshotCompares.push(await page.compareScreenshot());
|
||||
});
|
||||
|
||||
const waitForNavChange = async (page, routeChangedCount) => {
|
||||
await waitForFunctionTestContext((payload: any) => {
|
||||
return payload.routeChangedCount.count === 1;
|
||||
}, { routeChangedCount });
|
||||
|
||||
routeChangedCount.count = 0;
|
||||
};
|
||||
|
||||
@@ -93,62 +93,65 @@
|
||||
customElements.define('page-two', PageTwo);
|
||||
customElements.define('page-three', PageThree);
|
||||
|
||||
|
||||
window.Ionic.config.navAnimation = (AnimationC, navEl, opts) => {
|
||||
const TRANSLATEY = 'translateY';
|
||||
const OFF_BOTTOM = '40px';
|
||||
const CENTER = '0px';
|
||||
|
||||
const backDirection = (opts.direction === 'back');
|
||||
const enteringEl = opts.enteringEl;
|
||||
const leavingEl = opts.leavingEl;
|
||||
const ionPageElement = getIonPageElement(enteringEl);
|
||||
const enteringToolbarEle = ionPageElement.querySelector('ion-toolbar');
|
||||
const rootTransition = new AnimationC();
|
||||
|
||||
rootTransition
|
||||
.addElement(ionPageElement)
|
||||
.beforeRemoveClass('ion-page-invisible');
|
||||
|
||||
// animate the component itself
|
||||
if (backDirection) {
|
||||
const forceAnimationBuilder = new URLSearchParams(window.location.search).get('ionic:_forceAnimationBuilder');
|
||||
if (forceAnimationBuilder) {
|
||||
window.Ionic.config.navAnimation = (AnimationC, navEl, opts) => {
|
||||
const TRANSLATEY = 'translateY';
|
||||
const OFF_BOTTOM = '40px';
|
||||
const CENTER = '0px';
|
||||
|
||||
const backDirection = (opts.direction === 'back');
|
||||
const enteringEl = opts.enteringEl;
|
||||
const leavingEl = opts.leavingEl;
|
||||
const ionPageElement = getIonPageElement(enteringEl);
|
||||
const enteringToolbarEle = ionPageElement.querySelector('ion-toolbar');
|
||||
const rootTransition = new AnimationC();
|
||||
|
||||
rootTransition
|
||||
.duration(opts.duration || 200)
|
||||
.easing('cubic-bezier(0.47,0,0.745,0.715)');
|
||||
.addElement(ionPageElement)
|
||||
.beforeRemoveClass('ion-page-invisible');
|
||||
|
||||
// animate the component itself
|
||||
if (backDirection) {
|
||||
rootTransition
|
||||
.duration(opts.duration || 200)
|
||||
.easing('cubic-bezier(0.47,0,0.745,0.715)');
|
||||
|
||||
} else {
|
||||
rootTransition
|
||||
.duration(opts.duration || 280)
|
||||
.easing('cubic-bezier(0.36,0.66,0.04,1)')
|
||||
.fromTo(TRANSLATEY, OFF_BOTTOM, CENTER, true)
|
||||
.fromTo('opacity', 0.01, 1, true);
|
||||
}
|
||||
|
||||
// Animate toolbar if it's there
|
||||
if (enteringToolbarEle) {
|
||||
const enteringToolBar = new AnimationC();
|
||||
enteringToolBar.addElement(enteringToolbarEle);
|
||||
rootTransition.add(enteringToolBar);
|
||||
}
|
||||
|
||||
// setup leaving view
|
||||
if (leavingEl && backDirection) {
|
||||
// leaving content
|
||||
rootTransition
|
||||
.duration(opts.duration || 200)
|
||||
.easing('cubic-bezier(0.47,0,0.745,0.715)');
|
||||
|
||||
const leavingPage = new AnimationC();
|
||||
leavingPage
|
||||
.addElement(getIonPageElement(leavingEl))
|
||||
.fromTo(TRANSLATEY, CENTER, OFF_BOTTOM)
|
||||
.fromTo('opacity', 1, 0);
|
||||
|
||||
rootTransition.add(leavingPage);
|
||||
}
|
||||
|
||||
return Promise.resolve(rootTransition);
|
||||
};
|
||||
}
|
||||
|
||||
} else {
|
||||
rootTransition
|
||||
.duration(opts.duration || 280)
|
||||
.easing('cubic-bezier(0.36,0.66,0.04,1)')
|
||||
.fromTo(TRANSLATEY, OFF_BOTTOM, CENTER, true)
|
||||
.fromTo('opacity', 0.01, 1, true);
|
||||
}
|
||||
|
||||
// Animate toolbar if it's there
|
||||
if (enteringToolbarEle) {
|
||||
const enteringToolBar = new AnimationC();
|
||||
enteringToolBar.addElement(enteringToolbarEle);
|
||||
rootTransition.add(enteringToolBar);
|
||||
}
|
||||
|
||||
// setup leaving view
|
||||
if (leavingEl && backDirection) {
|
||||
// leaving content
|
||||
rootTransition
|
||||
.duration(opts.duration || 200)
|
||||
.easing('cubic-bezier(0.47,0,0.745,0.715)');
|
||||
|
||||
const leavingPage = new AnimationC();
|
||||
leavingPage
|
||||
.addElement(getIonPageElement(leavingEl))
|
||||
.fromTo(TRANSLATEY, CENTER, OFF_BOTTOM)
|
||||
.fromTo('opacity', 1, 0);
|
||||
|
||||
rootTransition.add(leavingPage);
|
||||
}
|
||||
|
||||
return Promise.resolve(rootTransition);
|
||||
};
|
||||
const getIonPageElement = (element) => {
|
||||
if (element.classList.contains('ion-page')) {
|
||||
return element;
|
||||
|
||||
Reference in New Issue
Block a user