feat: introduce puppeteer-firefox (#3628)

This adds a proof-of-concept of `puppeteer-firefox`.
This consists of two parts:
- `//experimental/juggler` - patches to apply to Firefox.
- `//experimental/puppeteer-firefox` - front-end code to
be merged with Puppeteer.

As things become more stable, we'll gradually move it out of
the experimental folder.
This commit is contained in:
Andrey Lushnikov
2018-12-06 11:24:00 -08:00
committed by GitHub
parent 8613e871fc
commit 45ab3e0332
164 changed files with 12861 additions and 0 deletions

View File

@@ -0,0 +1 @@
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">

View File

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<title>Detect Touch Test</title>
<script src='modernizr.js'></script>
</head>
<body style="font-size:30vmin">
<script>
document.body.textContent = Modernizr.touchevents ? 'YES' : 'NO';
</script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 413 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 387 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 B

View File

@@ -0,0 +1,15 @@
<script>
a();
function a() {
b();
}
function b() {
c();
}
function c() {
throw new Error('Fancy error!');
}
</script>

View File

@@ -0,0 +1,2 @@
import num from './es6module.js';
window.__es6injected = num;

View File

@@ -0,0 +1 @@
export default 42;

View File

@@ -0,0 +1,2 @@
import num from './es6/es6module.js';
window.__es6injected = num;

View File

@@ -0,0 +1,8 @@
<link rel='stylesheet' href='./style.css'>
<script src='./script.js' type='text/javascript'></script>
<style>
div {
line-height: 18px;
}
</style>
<div>Hi, I'm frame</div>

View File

@@ -0,0 +1,8 @@
<frameset>
<frameset>
<frame src='./frame.html'></frame>
<frame src='about:blank'></frame>
</frameset>
<frame src='/empty.html'></frame>
<frame></frame>
</frameset>

View File

@@ -0,0 +1,25 @@
<style>
body {
display: flex;
}
body iframe {
flex-grow: 1;
flex-shrink: 1;
}
::-webkit-scrollbar{
display: none;
}
</style>
<script>
async function attachFrame(frameId, url) {
var frame = document.createElement('iframe');
frame.src = url;
frame.id = frameId;
document.body.appendChild(frame);
await new Promise(x => frame.onload = x);
return 'kazakh';
}
</script>
<iframe src='./two-frames.html' name='2frames'></iframe>
<iframe src='./frame.html' name='aframe'></iframe>

View File

@@ -0,0 +1 @@
<iframe src='./frame.html'></iframe>

View File

@@ -0,0 +1 @@
console.log('Cheers!');

View File

@@ -0,0 +1,3 @@
div {
color: blue;
}

View File

@@ -0,0 +1,13 @@
<style>
body {
display: flex;
flex-direction: column;
}
body iframe {
flex-grow: 1;
flex-shrink: 1;
}
</style>
<iframe src='./frame.html' name='uno'></iframe>
<iframe src='./frame.html' name='dos'></iframe>

View File

@@ -0,0 +1,3 @@
<script>
var globalVar = 123;
</script>

View File

@@ -0,0 +1,52 @@
<script>
document.addEventListener('DOMContentLoaded', function() {
function generatePalette(amount) {
var result = [];
var hueStep = 360 / amount;
for (var i = 0; i < amount; ++i)
result.push('hsl(' + (hueStep * i) + ', 100%, 90%)');
return result;
}
var palette = generatePalette(100);
for (var i = 0; i < 200; ++i) {
var box = document.createElement('div');
box.classList.add('box');
box.style.setProperty('background-color', palette[i % palette.length]);
var x = i;
do {
var digit = x % 10;
x = (x / 10)|0;
var img = document.createElement('img');
img.src = `./digits/${digit}.png`;
box.insertBefore(img, box.firstChild);
} while (x);
document.body.appendChild(box);
}
});
</script>
<style>
body {
margin: 0;
padding: 0;
}
.box {
font-family: arial;
display: inline-flex;
align-items: center;
justify-content: center;
margin: 0;
padding: 0;
width: 50px;
height: 50px;
box-sizing: border-box;
border: 1px solid darkgray;
}
::-webkit-scrollbar {
display: none;
}
</style>

View File

@@ -0,0 +1,2 @@
window.__injected = 42;
window.__injectedError = new Error('hi');

View File

@@ -0,0 +1,3 @@
body {
background-color: red;
}

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<title>Button test</title>
</head>
<body>
<script src="mouse-helper.js"></script>
<button onclick="clicked();">Click target</button>
<script>
window.result = 'Was not clicked';
function clicked() {
result = 'Clicked';
}
</script>
</body>
</html>

View File

@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<title>Selection Test</title>
</head>
<body>
<label for="agree">Remember Me</label>
<input id="agree" type="checkbox">
<script>
window.result = {
check: null,
events: [],
};
let checkbox = document.querySelector('input');
const events = [
'change',
'click',
'dblclick',
'input',
'mousedown',
'mouseenter',
'mouseleave',
'mousemove',
'mouseout',
'mouseover',
'mouseup',
];
for (let event of events) {
checkbox.addEventListener(event, () => {
if (['change', 'click', 'dblclick', 'input'].includes(event) === true) {
result.check = checkbox.checked;
}
result.events.push(event);
}, false);
}
</script>
</body>
</html>

View File

@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<title>Keyboard test</title>
</head>
<body>
<textarea></textarea>
<script>
window.result = "";
let textarea = document.querySelector('textarea');
textarea.focus();
textarea.addEventListener('keydown', event => {
log('Keydown:', event.key, event.code, event.which, modifiers(event));
});
textarea.addEventListener('keypress', event => {
log('Keypress:', event.key, event.code, event.which, event.charCode, modifiers(event));
});
textarea.addEventListener('keyup', event => {
log('Keyup:', event.key, event.code, event.which, modifiers(event));
});
function modifiers(event) {
let m = [];
if (event.altKey)
m.push('Alt')
if (event.ctrlKey)
m.push('Control');
if (event.metaKey)
m.push('Meta')
if (event.shiftKey)
m.push('Shift')
return '[' + m.join(' ') + ']';
}
function log(...args) {
console.log.apply(console, args);
result += args.join(' ') + '\n';
}
function getResult() {
let temp = result.trim();
result = "";
return temp;
}
</script>
</body>
</html>

View File

@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<title>Scrollable test</title>
</head>
<body>
<script src='mouse-helper.js'></script>
<script>
for (let i = 0; i < 100; i++) {
let button = document.createElement('button');
button.textContent = i + ': not clicked';
button.id = 'button-' + i;
button.onclick = () => button.textContent = 'clicked';
button.oncontextmenu = event => {
event.preventDefault();
button.textContent = 'context menu';
}
document.body.appendChild(button);
document.body.appendChild(document.createElement('br'));
}
</script>
</body>
</html>

View File

@@ -0,0 +1,69 @@
<!DOCTYPE html>
<html>
<head>
<title>Selection Test</title>
</head>
<body>
<select>
<option value="black">Black</option>
<option value="blue">Blue</option>
<option value="brown">Brown</option>
<option value="cyan">Cyan</option>
<option value="gray">Gray</option>
<option value="green">Green</option>
<option value="indigo">Indigo</option>
<option value="magenta">Magenta</option>
<option value="orange">Orange</option>
<option value="pink">Pink</option>
<option value="purple">Purple</option>
<option value="red">Red</option>
<option value="violet">Violet</option>
<option value="white">White</option>
<option value="yellow">Yellow</option>
</select>
<script>
window.result = {
onInput: null,
onChange: null,
onBubblingChange: null,
onBubblingInput: null,
};
let select = document.querySelector('select');
function makeEmpty() {
for (let i = select.options.length - 1; i >= 0; --i) {
select.remove(i);
}
}
function makeMultiple() {
select.setAttribute('multiple', true);
}
select.addEventListener('input', () => {
result.onInput = Array.from(select.querySelectorAll('option:checked')).map((option) => {
return option.value;
});
}, false);
select.addEventListener('change', () => {
result.onChange = Array.from(select.querySelectorAll('option:checked')).map((option) => {
return option.value;
});
}, false);
document.body.addEventListener('input', () => {
result.onBubblingInput = Array.from(select.querySelectorAll('option:checked')).map((option) => {
return option.value;
});
}, false);
document.body.addEventListener('change', () => {
result.onBubblingChange = Array.from(select.querySelectorAll('option:checked')).map((option) => {
return option.value;
});
}, false);
</script>
</body>
</html>

View File

@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<title>Textarea test</title>
</head>
<body>
<textarea></textarea>
<script src='mouse-helper.js'></script>
<script>
window.result = '';
let textarea = document.querySelector('textarea');
textarea.addEventListener('input', () => result = textarea.value, false);
</script>
</body>
</html>

View File

@@ -0,0 +1 @@
<meta name = "viewport" content = "initial-scale = 1, user-scalable = no">

View File

@@ -0,0 +1,3 @@
/*! modernizr 3.5.0 (Custom Build) | MIT *
* https://modernizr.com/download/?-touchevents-setclasses !*/
!function(e,n,t){function o(e,n){return typeof e===n}function s(){var e,n,t,s,a,i,r;for(var l in c)if(c.hasOwnProperty(l)){if(e=[],n=c[l],n.name&&(e.push(n.name.toLowerCase()),n.options&&n.options.aliases&&n.options.aliases.length))for(t=0;t<n.options.aliases.length;t++)e.push(n.options.aliases[t].toLowerCase());for(s=o(n.fn,"function")?n.fn():n.fn,a=0;a<e.length;a++)i=e[a],r=i.split("."),1===r.length?Modernizr[r[0]]=s:(!Modernizr[r[0]]||Modernizr[r[0]]instanceof Boolean||(Modernizr[r[0]]=new Boolean(Modernizr[r[0]])),Modernizr[r[0]][r[1]]=s),f.push((s?"":"no-")+r.join("-"))}}function a(e){var n=u.className,t=Modernizr._config.classPrefix||"";if(p&&(n=n.baseVal),Modernizr._config.enableJSClass){var o=new RegExp("(^|\\s)"+t+"no-js(\\s|$)");n=n.replace(o,"$1"+t+"js$2")}Modernizr._config.enableClasses&&(n+=" "+t+e.join(" "+t),p?u.className.baseVal=n:u.className=n)}function i(){return"function"!=typeof n.createElement?n.createElement(arguments[0]):p?n.createElementNS.call(n,"http://www.w3.org/2000/svg",arguments[0]):n.createElement.apply(n,arguments)}function r(){var e=n.body;return e||(e=i(p?"svg":"body"),e.fake=!0),e}function l(e,t,o,s){var a,l,f,c,d="modernizr",p=i("div"),h=r();if(parseInt(o,10))for(;o--;)f=i("div"),f.id=s?s[o]:d+(o+1),p.appendChild(f);return a=i("style"),a.type="text/css",a.id="s"+d,(h.fake?h:p).appendChild(a),h.appendChild(p),a.styleSheet?a.styleSheet.cssText=e:a.appendChild(n.createTextNode(e)),p.id=d,h.fake&&(h.style.background="",h.style.overflow="hidden",c=u.style.overflow,u.style.overflow="hidden",u.appendChild(h)),l=t(p,e),h.fake?(h.parentNode.removeChild(h),u.style.overflow=c,u.offsetHeight):p.parentNode.removeChild(p),!!l}var f=[],c=[],d={_version:"3.5.0",_config:{classPrefix:"",enableClasses:!0,enableJSClass:!0,usePrefixes:!0},_q:[],on:function(e,n){var t=this;setTimeout(function(){n(t[e])},0)},addTest:function(e,n,t){c.push({name:e,fn:n,options:t})},addAsyncTest:function(e){c.push({name:null,fn:e})}},Modernizr=function(){};Modernizr.prototype=d,Modernizr=new Modernizr;var u=n.documentElement,p="svg"===u.nodeName.toLowerCase(),h=d._config.usePrefixes?" -webkit- -moz- -o- -ms- ".split(" "):["",""];d._prefixes=h;var m=d.testStyles=l;Modernizr.addTest("touchevents",function(){var t;if("ontouchstart"in e||e.DocumentTouch&&n instanceof DocumentTouch)t=!0;else{var o=["@media (",h.join("touch-enabled),("),"heartz",")","{#modernizr{top:9px;position:absolute}}"].join("");m(o,function(e){t=9===e.offsetTop})}return t}),s(),a(f),delete d.addTest,delete d.addAsyncTest;for(var v=0;v<Modernizr._q.length;v++)Modernizr._q[v]();e.Modernizr=Modernizr}(window,document);

View File

@@ -0,0 +1,36 @@
<style>
button {
position: absolute;
width: 100px;
height: 20px;
}
#btn0 { right: 0px; top: 0; }
#btn1 { right: -10px; top: 25px; }
#btn2 { right: -20px; top: 50px; }
#btn3 { right: -30px; top: 75px; }
#btn4 { right: -40px; top: 100px; }
#btn5 { right: -50px; top: 125px; }
#btn6 { right: -60px; top: 150px; }
#btn7 { right: -70px; top: 175px; }
#btn8 { right: -80px; top: 200px; }
#btn9 { right: -90px; top: 225px; }
#btn10 { right: -100px; top: 250px; }
</style>
<button id=btn0>0</button>
<button id=btn1>1</button>
<button id=btn2>2</button>
<button id=btn3>3</button>
<button id=btn4>4</button>
<button id=btn5>5</button>
<button id=btn6>6</button>
<button id=btn7>7</button>
<button id=btn8>8</button>
<button id=btn9>9</button>
<button id=btn10>10</button>
<script>
window.addEventListener('DOMContentLoaded', () => {
for (const button of Array.from(document.querySelectorAll('button')))
button.addEventListener('click', () => console.log('button #' + button.textContent + ' clicked'), false);
}, false);
</script>

View File

@@ -0,0 +1,3 @@
body {
background-color: pink;
}

View File

@@ -0,0 +1,2 @@
<link rel='stylesheet' href='./one-style.css'>
<div>hello, world!</div>

View File

@@ -0,0 +1,3 @@
<script>
window.result = window.injected;
</script>

View File

@@ -0,0 +1 @@
<title>Woof-Woof</title>

View File

@@ -0,0 +1,32 @@
<style>
:root {
font-family: monospace;
}
body {
display: flex;
align-items: center;
justify-content: center;
}
div {
width: 10ch;
word-wrap: break-word;
border: 1px solid blue;
transform: rotate(33deg);
line-height: 8ch;
padding: 2ch;
}
a {
margin-left: 7ch;
}
</style>
<div>
<a href='#clicked'>123321</a>
</div>
<script>
document.querySelector('a').addEventListener('click', () => {
window.__clicked = true;
});
</script>