blob: 633911d32786751832b1e30f4b9751c1d072a408 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import seedrandom from 'seedrandom';
import { ActionPlayback } from './ActionPlayback';
import * as timeline from './timeline';
let myRandom = new seedrandom('echarts-random');
// Random for echarts code.
// In case different echarts version called random different times.
// It will cause following random number all wrong.
let myRandom2 = new seedrandom('echarts-random-inner');
// Fixed random generator
Math.random = function () {
const val = myRandom();
return val;
};
window.__random__inner__ = function () {
const val = myRandom2();
return val;
};
let vstStarted = false;
window.__VRT_START__ = function () {
if (vstStarted) {
return;
}
vstStarted = true;
timeline.start();
// TODO not support reload without simpleRequire
if (window.__VRT_RUN_CONTEXT__) {
// Restore from previous run
setTimeout(async () => {
await __VRT_RUN_ACTIONS__(
window.__VRT_RUN_CONTEXT__.actions,
window.__VRT_RUN_CONTEXT__.currentActionIndex,
window.__VRT_RUN_CONTEXT__.currentActionContext
)
}, 1000);
}
else {
// Screenshot after 1000ms (200ms if 5x speed), wait the animation to be finished
setTimeout(async () => {
// Pause timeline until run actions.
timeline.pause();
await __VRT_FULL_SCREENSHOT__();
}, 1000);
}
}
function saveRunningContext(actions, actionIndex, playback) {
localStorage.setItem('vstRunContext', JSON.stringify({
actions: actions,
currentActionIndex: actionIndex,
currentActionContext: playback.getContext()
}));
}
window.__VRT_RUN_ACTIONS__ = async function (actions, restoredActionIndex, restoredActionContext) {
// Actions can only bu runned once.
timeline.resume();
const actionPlayback = new ActionPlayback();
const nativeLocation = window.location;
let currentActionIndex = 0;
// Some test cases change the params through reload().
// We need to save the running info and keep running after reload.
// window.location seems can't be redefined anymore. So we can only provide helper functions.
window.__VRT_RELOAD__ = function () {
// Mark reload triggered and let ActionPlayback stop.
window.__VRT_RELOAD_TRIGGERED__ = true;
saveRunningContext(actions, currentActionIndex, actionPlayback);
timeline.nativeSetTimeout(() => {
// CDPSession pay be disconnected if reload immediately.
nativeLocation.reload();
}, 100);
}
for (const [index, action] of actions.entries()) {
currentActionIndex = index;
if (index < restoredActionIndex) {
continue;
}
window.scrollTo(action.scrollX, action.scrollY);
await actionPlayback.runAction(action, index === restoredActionIndex ? restoredActionContext : null);
}
actionPlayback.stop();
__VRT_FINISH_ACTIONS__();
}
window.addEventListener('DOMContentLoaded', () => {
let style = document.createElement('style');
// Disable all css animation since it will cause screenshot inconsistent.
// PENDING Only tooltip? div[_echarts_instance_]>div
style.innerHTML = `
* {
transition-delay: 0s !important;
transition-duration: 0s !important;
animation-delay: -0.0001s !important;
animation-duration: 0s !important;
}
`;
document.head.appendChild(style);
// Prevent triggered mouseout event when mouse move out of window.
// DON"T know why, but it happens occasionally and cause hover state/ tooltip wrong before screenshot.
document.body.addEventListener('mouseout', e => {
if (!e.relatedTarget) {
e.stopPropagation();
e.stopImmediatePropagation();
}
}, true);
// Draw mouse
const box = document.createElement('puppeteer-mouse-pointer');
const styleElement = document.createElement('style');
styleElement.innerHTML = `
puppeteer-mouse-pointer {
pointer-events: none;
position: absolute;
top: 0;
z-index: 10000;
left: 0;
width: 20px;
height: 20px;
background: rgba(0,0,0,.4);
border: 1px solid white;
border-radius: 10px;
margin: -10px 0 0 -10px;
padding: 0;
transition: background .2s, border-radius .2s, border-color .2s;
}
puppeteer-mouse-pointer.button-1 {
transition: none;
background: rgba(0,0,0,0.9);
}
puppeteer-mouse-pointer.button-2 {
transition: none;
border-color: rgba(0,0,255,0.9);
}
puppeteer-mouse-pointer.button-3 {
transition: none;
border-radius: 4px;
}
puppeteer-mouse-pointer.button-4 {
transition: none;
border-color: rgba(255,0,0,0.9);
}
puppeteer-mouse-pointer.button-5 {
transition: none;
border-color: rgba(0,255,0,0.9);
}
`;
document.head.appendChild(styleElement);
document.body.appendChild(box);
document.addEventListener('mousemove', event => {
box.style.left = event.pageX + 'px';
box.style.top = event.pageY + 'px';
updateButtons(event.buttons);
}, true);
document.addEventListener('mousedown', event => {
updateButtons(event.buttons);
box.classList.add('button-' + event.which);
}, true);
document.addEventListener('mouseup', event => {
updateButtons(event.buttons);
box.classList.remove('button-' + event.which);
}, true);
function updateButtons(buttons) {
for (let i = 0; i < 5; i++) {
box.classList.toggle('button-' + i, buttons & (1 << i));
}
}
});