mirror of
https://github.com/microsoft/playwright-cli.git
synced 2026-09-14 19:59:39 +08:00
feat(ui): add react, make a small component (#158)
This is a first step to convert to React.
This commit is contained in:
Generated
+69
-4
@@ -1214,6 +1214,31 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.7.tgz",
|
||||
"integrity": "sha512-Zw1vhUSQZYw+7u5dAwNbIA9TuTotpzY/OF7sJM9FqPOF3SPjKnxrjoTktXDZgUjybf4cWVBP7O8wvKdSaGHweg=="
|
||||
},
|
||||
"@types/prop-types": {
|
||||
"version": "15.7.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz",
|
||||
"integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/react": {
|
||||
"version": "17.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.0.tgz",
|
||||
"integrity": "sha512-aj/L7RIMsRlWML3YB6KZiXB3fV2t41+5RBGYF8z+tAKU43Px8C3cYUZsDvf1/+Bm4FK21QWBrDutu8ZJ/70qOw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/prop-types": "*",
|
||||
"csstype": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"version": "17.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.0.tgz",
|
||||
"integrity": "sha512-lUqY7OlkF/RbNtD5nIq7ot8NquXrdFrjSOR6+w9a9RFQevGi1oZO1dcJbXMeONAPKtZ2UrZOEJ5UOCVsxbLk/g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"@types/source-list-map": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz",
|
||||
@@ -2491,6 +2516,12 @@
|
||||
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
|
||||
"dev": true
|
||||
},
|
||||
"csstype": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.5.tgz",
|
||||
"integrity": "sha512-uVDi8LpBUKQj6sdxNaTetL6FpeCqTjOvAQuQUa/qAqq8oOd4ivkbhgnqayl0dnPal8Tb/yB1tF+gOvCBiicaiQ==",
|
||||
"dev": true
|
||||
},
|
||||
"cyclist": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz",
|
||||
@@ -4518,8 +4549,7 @@
|
||||
"js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
|
||||
},
|
||||
"jsbn": {
|
||||
"version": "0.1.1",
|
||||
@@ -4636,6 +4666,14 @@
|
||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
|
||||
"dev": true
|
||||
},
|
||||
"loose-envify": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
||||
"requires": {
|
||||
"js-tokens": "^3.0.0 || ^4.0.0"
|
||||
}
|
||||
},
|
||||
"lower-case": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.1.tgz",
|
||||
@@ -5084,8 +5122,7 @@
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
||||
"dev": true
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
|
||||
},
|
||||
"object-copy": {
|
||||
"version": "0.1.0",
|
||||
@@ -5883,6 +5920,25 @@
|
||||
"safe-buffer": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"react": {
|
||||
"version": "17.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz",
|
||||
"integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.1.0",
|
||||
"object-assign": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"react-dom": {
|
||||
"version": "17.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.1.tgz",
|
||||
"integrity": "sha512-6eV150oJZ9U2t9svnsspTMrWNyHc6chX0KzDeAOXftRa8bNeOKTTfCJ7KorIwenkHd2xqVTBTCZd79yk/lx/Ug==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.1.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"scheduler": "^0.20.1"
|
||||
}
|
||||
},
|
||||
"react-is": {
|
||||
"version": "17.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz",
|
||||
@@ -6199,6 +6255,15 @@
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||
"dev": true
|
||||
},
|
||||
"scheduler": {
|
||||
"version": "0.20.1",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.1.tgz",
|
||||
"integrity": "sha512-LKTe+2xNJBNxu/QhHvDR14wUXHRQbVY5ZOYpOGWRzhydZUqrLb2JBvLPY7cAqFmqrWuDED0Mjk7013SZiOz6Bw==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.1.0",
|
||||
"object-assign": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"schema-utils": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",
|
||||
|
||||
+6
-2
@@ -31,12 +31,16 @@
|
||||
"dependencies": {
|
||||
"commander": "^6.1.0",
|
||||
"highlight.js": "^10.1.2",
|
||||
"playwright": "=1.7.0-next.1607623793189"
|
||||
"playwright": "=1.7.0-next.1607623793189",
|
||||
"react": "^17.0.1",
|
||||
"react-dom": "^17.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"folio": "^0.3.16",
|
||||
"@types/react": "^17.0.0",
|
||||
"@types/react-dom": "^17.0.0",
|
||||
"css-loader": "^4.3.0",
|
||||
"file-loader": "^6.1.0",
|
||||
"folio": "^0.3.16",
|
||||
"html-webpack-plugin": "^4.4.1",
|
||||
"monaco-editor": "^0.20.0",
|
||||
"pkg": "^4.4.9",
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Licensed 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.
|
||||
*/
|
||||
|
||||
.context-selector {
|
||||
min-width: 38px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 0;
|
||||
padding: 0 13px 0 5px;
|
||||
position: relative;
|
||||
height: 22px;
|
||||
align-self: center;
|
||||
margin-right: 20px;
|
||||
background: rgba(222, 222, 222, 0.3);
|
||||
color: white;
|
||||
border-radius: 3px;
|
||||
outline: none !important;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Licensed 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 * as React from 'react';
|
||||
import { ContextEntry } from '../../traceModel';
|
||||
import './contextSelector.css';
|
||||
|
||||
export const ContextSelector: React.FunctionComponent<{
|
||||
contexts: ContextEntry[],
|
||||
onChange: (contextEntry: ContextEntry) => void,
|
||||
}> = ({ contexts, onChange }) => {
|
||||
const [index, setIndex] = React.useState<number>(0);
|
||||
return (
|
||||
<select
|
||||
className='context-selector'
|
||||
style={{
|
||||
visibility: contexts.length <= 1 ? 'hidden' : 'visible',
|
||||
}}
|
||||
value={index}
|
||||
onChange={e => {
|
||||
const newIndex = +e.target.value;
|
||||
setIndex(newIndex);
|
||||
onChange(contexts[newIndex]);
|
||||
}}
|
||||
>
|
||||
{contexts.map((entry, index) => <option value={index} key={entry.name}>{entry.name}</option>)}
|
||||
</select>
|
||||
);
|
||||
};
|
||||
@@ -148,7 +148,9 @@ export class FilmStripView {
|
||||
updatePreview(clientX: number, time: number) {
|
||||
// TODO: pick file from the Y position.
|
||||
const video = this._videos[0];
|
||||
const metainfo = this._metainfo.get(video)!;
|
||||
const metainfo = this._metainfo.get(video);
|
||||
if (!metainfo)
|
||||
return;
|
||||
|
||||
const image = new Image(metainfo.width / 2 | 0, metainfo.height / 2 | 0);
|
||||
const index = (time - metainfo.startTime) / (metainfo.endTime - metainfo.startTime) * metainfo.frames | 0;
|
||||
|
||||
@@ -53,21 +53,6 @@
|
||||
flex: auto;
|
||||
}
|
||||
|
||||
.workbench .context-selector {
|
||||
min-width: 38px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 0;
|
||||
padding: 0 13px 0 5px;
|
||||
position: relative;
|
||||
height: 22px;
|
||||
align-self: center;
|
||||
margin-right: 20px;
|
||||
background: rgba(222, 222, 222, 0.3);
|
||||
color: white;
|
||||
border-radius: 3px;
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
tab-strip {
|
||||
background-color: var(--light-background);
|
||||
}
|
||||
|
||||
@@ -20,27 +20,24 @@ import { ActionListView } from './actionListView';
|
||||
import { PropertiesTabbedPane } from './propertiesTabbedPane';
|
||||
import { TimelineView } from './timelineView';
|
||||
import './workbench.css';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import * as React from 'react';
|
||||
import { ContextSelector } from './contextSelector';
|
||||
|
||||
export class Workbench {
|
||||
element: HTMLElement;
|
||||
private _tabbedPane: PropertiesTabbedPane | undefined;
|
||||
private _timelineGrid: TimelineView | undefined;
|
||||
private _contextSelector: HTMLSelectElement;
|
||||
private _contextSelectorDiv: HTMLElement;
|
||||
|
||||
constructor(trace: TraceModel) {
|
||||
this._contextSelector = dom`<select class="context-selector">${
|
||||
trace.contexts.map(entry => dom`<option>${entry.name}</option>`)
|
||||
}</select>` as HTMLElement as HTMLSelectElement;
|
||||
this._contextSelector.addEventListener('input', () => {
|
||||
this.showContext(trace.contexts[this._contextSelector.selectedIndex]);
|
||||
});
|
||||
if (trace.contexts.length === 1)
|
||||
this._contextSelector.style.visibility = 'hidden';
|
||||
this._contextSelectorDiv = dom`<div></div>`;
|
||||
this.element = dom`
|
||||
<vbox class="workbench">
|
||||
</vbox>
|
||||
`;
|
||||
window.addEventListener('resize', () => this.pack());
|
||||
ReactDOM.render(<ContextSelector contexts={trace.contexts} onChange={context => this.showContext(context)} />, this._contextSelectorDiv);
|
||||
this.showContext(trace.contexts[0]);
|
||||
}
|
||||
|
||||
@@ -55,7 +52,7 @@ export class Workbench {
|
||||
<div class="logo">🎭</div>
|
||||
<div class="product">Playwright</div>
|
||||
<div class="spacer"></div>
|
||||
${this._contextSelector}
|
||||
${this._contextSelectorDiv}
|
||||
</hbox>
|
||||
${this._timelineGrid.element}
|
||||
<hbox>
|
||||
@@ -7,7 +7,7 @@ module.exports = {
|
||||
app: path.join(__dirname, 'index.ts'),
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js']
|
||||
extensions: ['.ts', '.js', '.tsx', '.jsx']
|
||||
},
|
||||
output: {
|
||||
globalObject: 'self',
|
||||
@@ -17,7 +17,7 @@ module.exports = {
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.ts?$/,
|
||||
test: /\.(j|t)sx?$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/
|
||||
},
|
||||
|
||||
+3
-2
@@ -8,9 +8,10 @@
|
||||
"outDir": "./lib",
|
||||
"strict": true,
|
||||
"declaration": false,
|
||||
"noUnusedLocals": true
|
||||
"noUnusedLocals": true,
|
||||
"jsx": "react"
|
||||
},
|
||||
"compileOnSave": true,
|
||||
"include": ["src/**/*.ts"],
|
||||
"include": ["src/**/*.ts", "src/**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user