-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsync.js
More file actions
122 lines (91 loc) · 3.07 KB
/
Copy pathsync.js
File metadata and controls
122 lines (91 loc) · 3.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import path from 'path';
import express from 'express';
import { chromium } from 'playwright';
import { fileURLToPath } from 'url';
import { createServer } from 'node:http';
import { Server } from 'socket.io';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const startBrowser = ( host ) => {
return new Promise( async ( resolve, reject ) => {
try {
const browser = await chromium.launch( { headless: true } );
const page = await browser.newPage();
resolve( page );
} catch ( error ) {
reject( error );
}
} );
}
const getPageContent = async ( tab, host, port = 3000, socket = 3001, path = '/' ) => {
host = host.replace( /\/$/, '' ); // remove trailing slash from host
const url = host + path;
const response = await tab.goto( url, { timeout: 10000, waitUntil: 'domcontentloaded' } );
if ( await response.headerValue( 'content-type' ) !== 'text/html; charset=UTF-8' ) {
return '301';
}
if ( response.status() !== 200 && response.status() < 400 ) {
throw new Error( 'Could not load page, returned status ' + response.status() );
}
for( let el of await tab.locator( 'a[href]' ).all() ) {
// replace host url with localhost
await el.evaluate( ( link, port ) => {
const url = new URL( link.href );
url.hostname = 'localhost';
url.port = port;
url.protocol = 'http';
link.href = url.toString();
}, port );
}
let content = await tab.content();
content = content.replace( '</head>', `
<script>
var syncParams = { socket: ${socket} };
</script>
<script src="https://cdn.socket.io/4.7.5/socket.io.min.js" integrity="sha384-2huaZvOR9iDzHqslqwpR87isEmrfxqyWOF7hr7BY6KG0+hVKLoEXMPUJw3ynWuhO" crossorigin="anonymous"></script>
<script src="http://localhost:${port}/sync.js"></script>
</head>` );
return content;
}
const openSocket = ( app, port = 3000, socket = 3001 ) => {
const server = createServer( app );
const io = new Server( server, {
cors: {
origin: `http://localhost:${port}`,
}
} );
server.listen( socket );
return io;
}
export default async ( host, port = 3000, socket = 3001 ) => {
try {
const tab = await startBrowser( host );
const app = express();
app.use( '/', ( req, res ) => {
switch( req.url ) {
case '/sync.js':
return res.sendFile( __dirname + '/sync-listener.js' );
/*case '/socket.io.js':
const socketPath = require.resolve( 'socket.io-client/dist/socket.io.js' );
return res.sendFile( socketPath );*/
default:
getPageContent( tab, host, port, socket, req.url ).then( content => {
if ( content === '301' ) {
res.set( 'location', host + req.url );
res.status(301).send();
} else {
res.send( content );
}
} ).catch( error => {
console.error( 'Could not retrieve content. ' + error );
} );
}
} );
const server = app.listen( port );
const io = openSocket( app, port, socket );
console.log( 'Debug server running at http://localhost:' + port );
return { app, server, tab, io };
} catch ( error ) {
throw new Error( 'Could not load page debugger: ' + error );
}
}