2021-07-07 21:19:42 +03:00
/ * *
* Copyright Microsoft Corporation . All rights reserved .
*
* 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 .
* /
2023-05-26 17:03:41 +03:00
import type http from 'http' ;
2021-07-07 21:19:42 +03:00
import path from 'path' ;
2023-07-26 01:46:39 +03:00
import { test , expect , parseTestRunnerOutput } from './playwright-test-fixtures' ;
2023-05-26 17:03:41 +03:00
import { createHttpServer } from '../../packages/playwright-core/lib/utils/network' ;
2021-07-07 21:19:42 +03:00
2022-04-19 17:45:36 +03:00
const SIMPLE_SERVER_PATH = path . join ( __dirname , 'assets' , 'simple-server.js' ) ;
2021-07-07 21:19:42 +03:00
test ( 'should create a server' , async ( { runInlineTest } , { workerIndex } ) = > {
2023-01-21 05:24:15 +03:00
const port = workerIndex * 2 + 10500 ;
2021-07-07 21:19:42 +03:00
const result = await runInlineTest ( {
'test.spec.ts' : `
2023-02-15 06:20:56 +03:00
import { test , expect } from '@playwright/test' ;
2021-07-07 21:19:42 +03:00
test ( 'connect to the server via the baseURL' , async ( { baseURL , page } ) = > {
await page . goto ( '/hello' ) ;
await page . waitForURL ( '/hello' ) ;
expect ( page . url ( ) ) . toBe ( 'http://localhost:${port}/hello' ) ;
expect ( await page . textContent ( 'body' ) ) . toBe ( 'hello' ) ;
} ) ;
` ,
'playwright.config.ts' : `
module .exports = {
2021-08-04 00:24:14 +03:00
webServer : {
2022-04-19 17:45:36 +03:00
command : 'node ${JSON.stringify(SIMPLE_SERVER_PATH)} ${port}' ,
2021-08-04 00:24:14 +03:00
port : $ { port } ,
2021-07-14 20:01:46 +03:00
} ,
globalSetup : 'globalSetup.ts' ,
globalTeardown : 'globalTeardown.ts' ,
} ;
` ,
'globalSetup.ts' : `
2023-02-15 06:20:56 +03:00
import { expect } from '@playwright/test' ;
2022-07-08 01:27:21 +03:00
module .exports = async ( config ) = > {
expect ( config . webServer . port , "For backwards compatibility reasons, we ensure this shows up." ) . toBe ( $ { port } ) ;
2021-08-04 00:24:14 +03:00
const http = require ( "http" ) ;
const response = await new Promise ( resolve = > {
const request = http . request ( "http://localhost:${port}/hello" , resolve ) ;
request . end ( ) ;
} )
console . log ( 'globalSetup-status-' + response . statusCode )
return async ( ) = > {
const response = await new Promise ( resolve = > {
const request = http . request ( "http://localhost:${port}/hello" , resolve ) ;
request . end ( ) ;
} )
console . log ( 'globalSetup-teardown-status-' + response . statusCode )
} ;
2021-07-14 20:01:46 +03:00
} ;
` ,
'globalTeardown.ts' : `
module .exports = async ( ) = > {
const http = require ( "http" ) ;
const response = await new Promise ( resolve = > {
const request = http . request ( "http://localhost:${port}/hello" , resolve ) ;
request . end ( ) ;
} )
console . log ( 'globalTeardown-status-' + response . statusCode )
2021-07-07 21:19:42 +03:00
} ;
` ,
} ) ;
expect ( result . exitCode ) . toBe ( 0 ) ;
expect ( result . passed ) . toBe ( 1 ) ;
2022-02-18 18:54:01 +03:00
expect ( result . output ) . not . toContain ( '[WebServer] listening' ) ;
expect ( result . output ) . toContain ( '[WebServer] error from server' ) ;
2021-07-07 21:19:42 +03:00
expect ( result . report . suites [ 0 ] . specs [ 0 ] . tests [ 0 ] . results [ 0 ] . status ) . toContain ( 'passed' ) ;
2021-07-14 20:01:46 +03:00
2021-08-04 00:24:14 +03:00
const expectedLogMessages = [ 'globalSetup-status-200' , 'globalSetup-teardown-status' , 'globalTeardown-status-200' ] ;
2021-07-14 20:01:46 +03:00
const actualLogMessages = expectedLogMessages . map ( log = > ( {
log ,
index : result.output.indexOf ( log ) ,
} ) ) . sort ( ( a , b ) = > a . index - b . index ) . filter ( l = > l . index !== - 1 ) . map ( l = > l . log ) ;
expect ( actualLogMessages ) . toStrictEqual ( expectedLogMessages ) ;
2021-07-07 21:19:42 +03:00
} ) ;
test ( 'should create a server with environment variables' , async ( { runInlineTest } , { workerIndex } ) = > {
2023-01-21 05:24:15 +03:00
const port = workerIndex * 2 + 10500 ;
2023-08-11 19:37:14 +03:00
process . env [ 'FOOEXTERNAL' ] = 'EXTERNAL-BAR' ;
2021-07-07 21:19:42 +03:00
const result = await runInlineTest ( {
'test.spec.ts' : `
2023-02-15 06:20:56 +03:00
import { test , expect } from '@playwright/test' ;
2021-07-07 21:19:42 +03:00
test ( 'connect to the server' , async ( { baseURL , page } ) = > {
expect ( baseURL ) . toBe ( 'http://localhost:${port}' ) ;
await page . goto ( baseURL + '/env-FOO' ) ;
expect ( await page . textContent ( 'body' ) ) . toBe ( 'BAR' ) ;
2023-08-11 19:37:14 +03:00
await page . goto ( baseURL + '/env-FOOEXTERNAL' ) ;
expect ( await page . textContent ( 'body' ) ) . toBe ( 'EXTERNAL-BAR' ) ;
2021-07-07 21:19:42 +03:00
} ) ;
` ,
'playwright.config.ts' : `
module .exports = {
2021-08-04 00:24:14 +03:00
webServer : {
2022-04-19 17:45:36 +03:00
command : 'node ${JSON.stringify(SIMPLE_SERVER_PATH)} ${port}' ,
2021-08-04 00:24:14 +03:00
port : $ { port } ,
2021-07-07 21:19:42 +03:00
env : {
'FOO' : 'BAR' ,
}
}
} ;
` ,
2022-02-18 18:54:01 +03:00
} , { } , { DEBUG : 'pw:webserver' } ) ;
2021-07-07 21:19:42 +03:00
expect ( result . exitCode ) . toBe ( 0 ) ;
expect ( result . passed ) . toBe ( 1 ) ;
2022-02-18 18:54:01 +03:00
expect ( result . output ) . toContain ( '[WebServer] listening' ) ;
expect ( result . output ) . toContain ( '[WebServer] error from server' ) ;
2021-07-07 21:19:42 +03:00
expect ( result . report . suites [ 0 ] . specs [ 0 ] . tests [ 0 ] . results [ 0 ] . status ) . toContain ( 'passed' ) ;
2023-08-11 19:37:14 +03:00
delete process . env [ 'FOOEXTERNAL' ] ;
2021-07-07 21:19:42 +03:00
} ) ;
2022-04-19 17:45:36 +03:00
test ( 'should default cwd to config directory' , async ( { runInlineTest } , testInfo ) = > {
2023-01-21 05:24:15 +03:00
const port = testInfo . workerIndex * 2 + 10500 ;
2022-04-19 17:45:36 +03:00
const configDir = testInfo . outputPath ( 'foo' ) ;
const relativeSimpleServerPath = path . relative ( configDir , SIMPLE_SERVER_PATH ) ;
const result = await runInlineTest ( {
'foo/test.spec.ts' : `
2023-02-15 06:20:56 +03:00
import { test , expect } from '@playwright/test' ;
2022-04-19 17:45:36 +03:00
test ( 'connect to the server' , async ( { baseURL } ) = > {
expect ( baseURL ) . toBe ( 'http://localhost:${port}' ) ;
} ) ;
` ,
'foo/playwright.config.ts' : `
module .exports = {
webServer : {
command : 'node ${JSON.stringify(relativeSimpleServerPath)} ${port}' ,
port : $ { port } ,
}
} ;
` ,
} , { } , { DEBUG : 'pw:webserver' } , {
cwd : 'foo'
} ) ;
expect ( result . exitCode ) . toBe ( 0 ) ;
expect ( result . passed ) . toBe ( 1 ) ;
expect ( result . output ) . toContain ( '[WebServer] listening' ) ;
expect ( result . output ) . toContain ( '[WebServer] error from server' ) ;
} ) ;
test ( 'should resolve cwd wrt config directory' , async ( { runInlineTest } , testInfo ) = > {
2023-01-21 05:24:15 +03:00
const port = testInfo . workerIndex * 2 + 10500 ;
2022-04-19 17:45:36 +03:00
const testdir = testInfo . outputPath ( ) ;
const relativeSimpleServerPath = path . relative ( testdir , SIMPLE_SERVER_PATH ) ;
const result = await runInlineTest ( {
'foo/test.spec.ts' : `
2023-02-15 06:20:56 +03:00
import { test , expect } from '@playwright/test' ;
2022-04-19 17:45:36 +03:00
test ( 'connect to the server' , async ( { baseURL } ) = > {
expect ( baseURL ) . toBe ( 'http://localhost:${port}' ) ;
} ) ;
` ,
'foo/playwright.config.ts' : `
module .exports = {
webServer : {
command : 'node ${JSON.stringify(relativeSimpleServerPath)} ${port}' ,
port : $ { port } ,
cwd : '..' ,
}
} ;
` ,
} , { } , { DEBUG : 'pw:webserver' } , {
cwd : 'foo'
} ) ;
expect ( result . exitCode ) . toBe ( 0 ) ;
expect ( result . passed ) . toBe ( 1 ) ;
expect ( result . output ) . toContain ( '[WebServer] listening' ) ;
expect ( result . output ) . toContain ( '[WebServer] error from server' ) ;
} ) ;
2022-01-27 03:32:58 +03:00
test ( 'should create a server with url' , async ( { runInlineTest } , { workerIndex } ) = > {
2023-01-21 05:24:15 +03:00
const port = workerIndex * 2 + 10500 ;
2022-01-27 03:32:58 +03:00
const result = await runInlineTest ( {
'test.spec.ts' : `
2023-02-15 06:20:56 +03:00
import { test , expect } from '@playwright/test' ;
2022-01-27 03:32:58 +03:00
test ( 'connect to the server' , async ( { baseURL , page } ) = > {
2022-02-09 02:57:36 +03:00
expect ( baseURL ) . toBe ( undefined ) ;
await page . goto ( 'http://localhost:${port}/ready' ) ;
2022-01-27 03:32:58 +03:00
expect ( await page . textContent ( 'body' ) ) . toBe ( 'hello' ) ;
} ) ;
` ,
'playwright.config.ts' : `
module .exports = {
webServer : {
command : 'node ${JSON.stringify(path.join(__dirname, ' assets ', ' simple - server - with - ready - route . js '))} ${port}' ,
url : 'http://localhost:${port}/ready'
}
} ;
` ,
} ) ;
expect ( result . exitCode ) . toBe ( 0 ) ;
expect ( result . passed ) . toBe ( 1 ) ;
expect ( result . report . suites [ 0 ] . specs [ 0 ] . tests [ 0 ] . results [ 0 ] . status ) . toContain ( 'passed' ) ;
} ) ;
2021-07-07 21:19:42 +03:00
test ( 'should time out waiting for a server' , async ( { runInlineTest } , { workerIndex } ) = > {
2023-01-21 05:24:15 +03:00
const port = workerIndex * 2 + 10500 ;
2021-07-07 21:19:42 +03:00
const result = await runInlineTest ( {
'test.spec.ts' : `
2023-02-15 06:20:56 +03:00
import { test , expect } from '@playwright/test' ;
2021-07-07 21:19:42 +03:00
test ( 'connect to the server' , async ( { baseURL , page } ) = > {
expect ( baseURL ) . toBe ( 'http://localhost:${port}' ) ;
await page . goto ( baseURL + '/hello' ) ;
expect ( await page . textContent ( 'body' ) ) . toBe ( 'hello' ) ;
} ) ;
` ,
'playwright.config.ts' : `
module .exports = {
2021-08-04 00:24:14 +03:00
webServer : {
2022-04-19 17:45:36 +03:00
command : 'node ${JSON.stringify(SIMPLE_SERVER_PATH)} ${port} 1000' ,
2021-08-04 00:24:14 +03:00
port : $ { port } ,
timeout : 100 ,
2021-07-07 21:19:42 +03:00
}
} ;
` ,
} ) ;
expect ( result . exitCode ) . toBe ( 1 ) ;
2021-09-27 12:32:57 +03:00
expect ( result . output ) . toContain ( ` Timed out waiting 100ms from config.webServer. ` ) ;
2021-07-07 21:19:42 +03:00
} ) ;
2022-01-27 03:32:58 +03:00
test ( 'should time out waiting for a server with url' , async ( { runInlineTest } , { workerIndex } ) = > {
2023-01-21 05:24:15 +03:00
const port = workerIndex * 2 + 10500 ;
2022-01-27 03:32:58 +03:00
const result = await runInlineTest ( {
'test.spec.ts' : `
2023-02-15 06:20:56 +03:00
import { test , expect } from '@playwright/test' ;
2022-01-27 03:32:58 +03:00
test ( 'connect to the server' , async ( { baseURL , page } ) = > {
expect ( baseURL ) . toBe ( 'http://localhost:${port}/ready' ) ;
await page . goto ( baseURL ) ;
expect ( await page . textContent ( 'body' ) ) . toBe ( 'hello' ) ;
} ) ;
` ,
'playwright.config.ts' : `
module .exports = {
webServer : {
command : 'node ${JSON.stringify(path.join(__dirname, ' assets ', ' simple - server - with - ready - route . js '))} ${port}' ,
url : 'http://localhost:${port}/ready' ,
timeout : 300 ,
}
} ;
` ,
} ) ;
expect ( result . exitCode ) . toBe ( 1 ) ;
expect ( result . output ) . toContain ( ` Timed out waiting 300ms from config.webServer. ` ) ;
} ) ;
2021-07-15 02:19:45 +03:00
test ( 'should be able to specify the baseURL without the server' , async ( { runInlineTest } , { workerIndex } ) = > {
2023-01-21 05:24:15 +03:00
const port = workerIndex * 2 + 10500 ;
2023-05-26 17:03:41 +03:00
const server = createHttpServer ( ( req : http.IncomingMessage , res : http.ServerResponse ) = > {
2021-07-15 02:19:45 +03:00
res . end ( '<html><body>hello</body></html>' ) ;
} ) ;
2021-10-02 05:40:47 +03:00
await new Promise < void > ( resolve = > server . listen ( port , resolve ) ) ;
2021-07-07 21:19:42 +03:00
const result = await runInlineTest ( {
'test.spec.ts' : `
2023-02-15 06:20:56 +03:00
import { test , expect } from '@playwright/test' ;
2021-07-07 21:19:42 +03:00
test ( 'connect to the server' , async ( { baseURL , page } ) = > {
expect ( baseURL ) . toBe ( 'http://localhost:${port}' ) ;
await page . goto ( baseURL + '/hello' ) ;
expect ( await page . textContent ( 'body' ) ) . toBe ( 'hello' ) ;
} ) ;
` ,
'playwright.config.ts' : `
module .exports = {
2021-07-15 02:19:45 +03:00
use : {
baseURL : 'http://localhost:${port}' ,
2021-07-07 21:19:42 +03:00
}
} ;
` ,
} ) ;
expect ( result . exitCode ) . toBe ( 0 ) ;
expect ( result . passed ) . toBe ( 1 ) ;
expect ( result . report . suites [ 0 ] . specs [ 0 ] . tests [ 0 ] . results [ 0 ] . status ) . toContain ( 'passed' ) ;
2021-07-15 02:19:45 +03:00
await new Promise ( resolve = > server . close ( resolve ) ) ;
2021-07-07 21:19:42 +03:00
} ) ;
2021-11-29 19:41:26 +03:00
test ( 'should be able to specify a custom baseURL with the server' , async ( { runInlineTest } , { workerIndex } ) = > {
2023-01-20 19:36:31 +03:00
const customWebServerPort = workerIndex * 2 + 10500 ;
2021-11-29 19:41:26 +03:00
const webServerPort = customWebServerPort + 1 ;
2023-05-26 17:03:41 +03:00
const server = createHttpServer ( ( req : http.IncomingMessage , res : http.ServerResponse ) = > {
2021-11-29 19:41:26 +03:00
res . end ( '<html><body>hello</body></html>' ) ;
} ) ;
await new Promise < void > ( resolve = > server . listen ( customWebServerPort , resolve ) ) ;
const result = await runInlineTest ( {
'test.spec.ts' : `
2023-02-15 06:20:56 +03:00
import { test , expect } from '@playwright/test' ;
2021-11-29 19:41:26 +03:00
test ( 'connect to the server' , async ( { baseURL , page } ) = > {
expect ( baseURL ) . toBe ( 'http://localhost:${customWebServerPort}' ) ;
await page . goto ( baseURL + '/hello' ) ;
expect ( await page . textContent ( 'body' ) ) . toBe ( 'hello' ) ;
} ) ;
` ,
'playwright.config.ts' : `
module .exports = {
webServer : {
2022-04-19 17:45:36 +03:00
command : 'node ${JSON.stringify(SIMPLE_SERVER_PATH)} ${webServerPort}' ,
2021-11-29 19:41:26 +03:00
port : $ { webServerPort } ,
} ,
use : {
baseURL : 'http://localhost:${customWebServerPort}' ,
}
} ;
` ,
} ) ;
expect ( result . exitCode ) . toBe ( 0 ) ;
expect ( result . passed ) . toBe ( 1 ) ;
expect ( result . report . suites [ 0 ] . specs [ 0 ] . tests [ 0 ] . results [ 0 ] . status ) . toContain ( 'passed' ) ;
await new Promise ( resolve = > server . close ( resolve ) ) ;
} ) ;
2022-08-10 22:48:37 +03:00
test ( 'should be able to use an existing server when reuseExistingServer:true' , async ( { runInlineTest } , { workerIndex } ) = > {
2023-01-21 05:24:15 +03:00
const port = workerIndex * 2 + 10500 ;
2023-05-26 17:03:41 +03:00
const server = createHttpServer ( ( req : http.IncomingMessage , res : http.ServerResponse ) = > {
2021-07-07 21:19:42 +03:00
res . end ( '<html><body>hello</body></html>' ) ;
} ) ;
2021-10-02 05:40:47 +03:00
await new Promise < void > ( resolve = > server . listen ( port , resolve ) ) ;
2021-07-07 21:19:42 +03:00
const result = await runInlineTest ( {
'test.spec.ts' : `
2023-02-15 06:20:56 +03:00
import { test , expect } from '@playwright/test' ;
2021-07-15 02:19:45 +03:00
test ( 'connect to the server via the baseURL' , async ( { baseURL , page } ) = > {
await page . goto ( '/hello' ) ;
await page . waitForURL ( '/hello' ) ;
expect ( page . url ( ) ) . toBe ( 'http://localhost:${port}/hello' ) ;
2021-07-07 21:19:42 +03:00
expect ( await page . textContent ( 'body' ) ) . toBe ( 'hello' ) ;
} ) ;
` ,
'playwright.config.ts' : `
module .exports = {
2021-08-04 00:24:14 +03:00
webServer : {
2022-04-19 17:45:36 +03:00
command : 'node ${JSON.stringify(SIMPLE_SERVER_PATH)} ${port}' ,
2021-08-04 00:24:14 +03:00
port : $ { port } ,
reuseExistingServer : true ,
2021-07-07 21:19:42 +03:00
}
} ;
` ,
} ) ;
expect ( result . exitCode ) . toBe ( 0 ) ;
expect ( result . passed ) . toBe ( 1 ) ;
2021-09-27 12:32:57 +03:00
expect ( result . output ) . not . toContain ( '[WebServer] ' ) ;
2021-07-15 02:19:45 +03:00
expect ( result . report . suites [ 0 ] . specs [ 0 ] . tests [ 0 ] . results [ 0 ] . status ) . toContain ( 'passed' ) ;
await new Promise ( resolve = > server . close ( resolve ) ) ;
} ) ;
2022-08-10 22:48:37 +03:00
test ( 'should throw when a server is already running on the given port and strict is true' , async ( { runInlineTest } , { workerIndex } ) = > {
2023-01-21 05:24:15 +03:00
const port = workerIndex * 2 + 10500 ;
2023-05-26 17:03:41 +03:00
const server = createHttpServer ( ( req : http.IncomingMessage , res : http.ServerResponse ) = > {
2021-07-15 02:19:45 +03:00
res . end ( '<html><body>hello</body></html>' ) ;
} ) ;
2021-10-02 05:40:47 +03:00
await new Promise < void > ( resolve = > server . listen ( port , resolve ) ) ;
2021-07-15 02:19:45 +03:00
const result = await runInlineTest ( {
'test.spec.ts' : `
2023-02-15 06:20:56 +03:00
import { test , expect } from '@playwright/test' ;
2021-07-15 02:19:45 +03:00
test ( 'connect to the server via the baseURL' , async ( { baseURL , page } ) = > {
await page . goto ( '/hello' ) ;
await page . waitForURL ( '/hello' ) ;
expect ( page . url ( ) ) . toBe ( 'http://localhost:${port}/hello' ) ;
expect ( await page . textContent ( 'body' ) ) . toBe ( 'hello' ) ;
} ) ;
` ,
'playwright.config.ts' : `
module .exports = {
2021-08-04 00:24:14 +03:00
webServer : {
2022-04-19 17:45:36 +03:00
command : 'node ${JSON.stringify(SIMPLE_SERVER_PATH)} ${port}' ,
2021-08-04 00:24:14 +03:00
port : $ { port } ,
reuseExistingServer : false ,
2021-07-15 02:19:45 +03:00
}
} ;
` ,
} ) ;
expect ( result . exitCode ) . toBe ( 1 ) ;
2022-01-27 03:32:58 +03:00
expect ( result . output ) . toContain ( ` http://localhost: ${ port } is already used, make sure that nothing is running on the port/url ` ) ;
2021-07-15 02:19:45 +03:00
await new Promise ( resolve = > server . close ( resolve ) ) ;
} ) ;
2021-09-02 19:39:41 +03:00
for ( const host of [ 'localhost' , '127.0.0.1' , '0.0.0.0' ] ) {
test ( ` should detect the server if a web-server is already running on ${ host } ` , async ( { runInlineTest } , { workerIndex } ) = > {
2023-01-21 05:24:15 +03:00
const port = workerIndex * 2 + 10500 ;
2023-05-26 17:03:41 +03:00
const server = createHttpServer ( ( req : http.IncomingMessage , res : http.ServerResponse ) = > {
2021-09-02 19:39:41 +03:00
res . end ( '<html><body>hello</body></html>' ) ;
} ) ;
2021-10-02 05:40:47 +03:00
await new Promise < void > ( resolve = > server . listen ( port , host , resolve ) ) ;
2021-09-02 19:39:41 +03:00
try {
const result = await runInlineTest ( {
'test.spec.ts' : `
2023-02-15 06:20:56 +03:00
import { test , expect } from '@playwright/test' ;
2021-09-02 19:39:41 +03:00
test ( 'connect to the server via the baseURL' , async ( { baseURL , page } ) = > {
await page . goto ( '/hello' ) ;
expect ( await page . textContent ( 'body' ) ) . toBe ( 'hello' ) ;
} ) ;
` ,
'playwright.config.ts' : `
module .exports = {
webServer : {
command : 'node -e "process.exit(1)"' ,
port : $ { port } ,
reuseExistingServer : false ,
}
} ;
` ,
} ) ;
expect ( result . exitCode ) . toBe ( 1 ) ;
2022-01-27 03:32:58 +03:00
expect ( result . output ) . toContain ( ` http://localhost: ${ port } is already used, make sure that nothing is running on the port/url ` ) ;
2021-09-02 19:39:41 +03:00
} finally {
await new Promise ( resolve = > server . close ( resolve ) ) ;
}
} ) ;
}
2022-03-24 19:30:52 +03:00
2022-08-10 22:48:37 +03:00
test ( ` should support self signed certificate ` , async ( { runInlineTest , httpsServer } ) = > {
2022-03-24 19:30:52 +03:00
const result = await runInlineTest ( {
'test.spec.js' : `
2023-02-15 06:20:56 +03:00
import { test , expect } from '@playwright/test' ;
2022-03-24 19:30:52 +03:00
test ( 'pass' , async ( { } ) = > { } ) ;
` ,
'playwright.config.js' : `
2022-05-04 00:25:56 +03:00
module .exports = {
webServer : {
url : '${httpsServer.EMPTY_PAGE}' ,
ignoreHTTPSErrors : true ,
reuseExistingServer : true ,
} ,
} ;
` ,
2022-03-24 19:30:52 +03:00
} ) ;
expect ( result . exitCode ) . toBe ( 0 ) ;
} ) ;
2022-04-29 01:08:10 +03:00
2022-08-10 22:48:37 +03:00
test ( 'should send Accept header' , async ( { runInlineTest , server } ) = > {
let acceptHeader : string | undefined | null = null ;
server . setRoute ( '/hello' , ( req , res ) = > {
if ( acceptHeader === null ) acceptHeader = req . headers . accept ;
res . end ( '<html><body>hello</body></html>' ) ;
} ) ;
const result = await runInlineTest ( {
'test.spec.ts' : `
2023-02-15 06:20:56 +03:00
import { test , expect } from '@playwright/test' ;
2022-08-10 22:48:37 +03:00
test ( 'connect to the server' , async ( { baseURL , page } ) = > {
await page . goto ( 'http://localhost:${server.PORT}/hello' ) ;
expect ( await page . textContent ( 'body' ) ) . toBe ( 'hello' ) ;
} ) ;
` ,
'playwright.config.ts' : `
module .exports = {
webServer : {
command : 'node ${JSON.stringify(SIMPLE_SERVER_PATH)} ${server.PORT}' ,
url : 'http://localhost:${server.PORT}/hello' ,
reuseExistingServer : true ,
}
} ;
` ,
} ) ;
expect ( result . exitCode ) . toBe ( 0 ) ;
expect ( acceptHeader ) . toBe ( '*/*' ) ;
} ) ;
2023-04-05 11:39:35 +03:00
test ( 'should follow redirects' , async ( { runInlineTest , server } ) = > {
server . setRedirect ( '/redirect' , '/redirected-to' ) ;
server . setRoute ( '/redirected-to' , ( req , res ) = > {
res . end ( '<html><body>hello</body></html>' ) ;
} ) ;
const result = await runInlineTest ( {
'test.spec.ts' : `
import { test , expect } from '@playwright/test' ;
test ( 'connect to the server' , async ( { baseURL , page } ) = > {
await page . goto ( 'http://localhost:${server.PORT}/redirect' ) ;
expect ( await page . textContent ( 'body' ) ) . toBe ( 'hello' ) ;
} ) ;
` ,
'playwright.config.ts' : `
module .exports = {
webServer : {
command : 'node ${JSON.stringify(SIMPLE_SERVER_PATH)} ${server.PORT}' ,
url : 'http://localhost:${server.PORT}/redirect' ,
reuseExistingServer : true ,
}
} ;
` ,
} ) ;
expect ( result . exitCode ) . toBe ( 0 ) ;
} ) ;
2022-04-29 01:08:10 +03:00
test ( 'should create multiple servers' , async ( { runInlineTest } , { workerIndex } ) = > {
2023-01-20 19:36:31 +03:00
const port = workerIndex * 2 + 10500 ;
2022-04-29 01:08:10 +03:00
const result = await runInlineTest ( {
'test.spec.ts' : `
2023-02-15 06:20:56 +03:00
import { test , expect } from '@playwright/test' ;
2022-05-04 00:25:56 +03:00
2022-04-29 01:08:10 +03:00
test ( 'connect to the server' , async ( { page } ) = > {
await page . goto ( 'http://localhost:${port}/port' ) ;
await page . locator ( 'text=${port}' ) ;
await page . goto ( 'http://localhost:${port + 1}/port' ) ;
await page . locator ( 'text=${port + 1}' ) ;
} ) ;
` ,
'playwright.config.ts' : `
module .exports = {
2022-07-08 01:27:21 +03:00
webServer : [
{
command : 'node ${JSON.stringify(SIMPLE_SERVER_PATH)} ${port}' ,
url : 'http://localhost:${port}/port' ,
} ,
{
command : 'node ${JSON.stringify(SIMPLE_SERVER_PATH)} ${port + 1}' ,
url : 'http://localhost:${port + 1}/port' ,
}
] ,
2022-05-04 00:25:56 +03:00
globalSetup : 'globalSetup.ts' ,
globalTeardown : 'globalTeardown.ts' ,
} ;
2022-04-29 01:08:10 +03:00
` ,
'globalSetup.ts' : `
2023-02-15 06:20:56 +03:00
import { expect } from '@playwright/test' ;
2022-07-08 01:27:21 +03:00
module .exports = async ( config ) = > {
expect ( config . webServer , "The public API defines this type as singleton or null, so if using array style we fallback to null to avoid having the type lie to the user." ) . toBe ( null ) ;
2022-05-04 00:25:56 +03:00
const http = require ( "http" ) ;
const response = await new Promise ( resolve = > {
const request = http . request ( "http://localhost:${port}/hello" , resolve ) ;
request . end ( ) ;
} )
console . log ( 'globalSetup-status-' + response . statusCode )
return async ( ) = > {
2022-04-29 01:08:10 +03:00
const response = await new Promise ( resolve = > {
const request = http . request ( "http://localhost:${port}/hello" , resolve ) ;
request . end ( ) ;
} )
2022-05-04 00:25:56 +03:00
console . log ( 'globalSetup-teardown-status-' + response . statusCode )
2022-04-29 01:08:10 +03:00
} ;
2022-05-04 00:25:56 +03:00
} ;
2022-04-29 01:08:10 +03:00
` ,
'globalTeardown.ts' : `
2022-05-04 00:25:56 +03:00
module .exports = async ( ) = > {
const http = require ( "http" ) ;
const response = await new Promise ( resolve = > {
const request = http . request ( "http://localhost:${port}/hello" , resolve ) ;
request . end ( ) ;
} )
console . log ( 'globalTeardown-status-' + response . statusCode )
} ;
2022-04-29 01:08:10 +03:00
` ,
} , undefined , { DEBUG : 'pw:webserver' } ) ;
expect ( result . exitCode ) . toBe ( 0 ) ;
expect ( result . passed ) . toBe ( 1 ) ;
expect ( result . output ) . toContain ( '[WebServer] listening' ) ;
expect ( result . output ) . toContain ( '[WebServer] error from server' ) ;
expect ( result . output ) . toContain ( 'passed' ) ;
const expectedLogMessages = [ 'globalSetup-status-200' , 'globalSetup-teardown-status' , 'globalTeardown-status-200' ] ;
const actualLogMessages = expectedLogMessages . map ( log = > ( {
log ,
index : result.output.indexOf ( log ) ,
} ) ) . sort ( ( a , b ) = > a . index - b . index ) . filter ( l = > l . index !== - 1 ) . map ( l = > l . log ) ;
expect ( actualLogMessages ) . toStrictEqual ( expectedLogMessages ) ;
} ) ;
test . describe ( 'baseURL with plugins' , ( ) = > {
test ( 'plugins do not set it' , async ( { runInlineTest } , { workerIndex } ) = > {
2023-01-20 19:36:31 +03:00
const port = workerIndex * 2 + 10500 ;
2022-04-29 01:08:10 +03:00
const result = await runInlineTest ( {
'test.spec.ts' : `
2023-02-15 06:20:56 +03:00
import { test , expect } from '@playwright/test' ;
2023-01-28 01:36:41 +03:00
test ( 'connect to the server' , async ( { baseURL , page } ) = > {
expect ( baseURL ) . toBeUndefined ( ) ;
} ) ;
` ,
'playwright.config.ts' : `
import { webServer } from '@playwright/test/lib/plugins' ;
module .exports = {
_plugins : [
webServer ( {
command : 'node ${JSON.stringify(SIMPLE_SERVER_PATH)} ${port}' ,
url : 'http://localhost:${port}/port' ,
} )
]
} ;
2022-05-04 00:25:56 +03:00
` ,
2022-04-29 01:08:10 +03:00
} , undefined , { DEBUG : 'pw:webserver' } ) ;
expect ( result . exitCode ) . toBe ( 0 ) ;
expect ( result . passed ) . toBe ( 1 ) ;
} ) ;
test ( 'legacy config sets it alongside plugin' , async ( { runInlineTest } , { workerIndex } ) = > {
2023-01-20 19:36:31 +03:00
const port = workerIndex * 2 + 10500 ;
2022-04-29 01:08:10 +03:00
const result = await runInlineTest ( {
'test.spec.ts' : `
2023-02-15 06:20:56 +03:00
import { test , expect } from '@playwright/test' ;
2023-01-28 01:36:41 +03:00
test ( 'connect to the server' , async ( { baseURL , page } ) = > {
expect ( baseURL ) . toBe ( 'http://localhost:${port}' ) ;
} ) ;
` ,
2022-04-29 01:08:10 +03:00
'playwright.config.ts' : `
2023-01-28 01:36:41 +03:00
import { webServer } from '@playwright/test/lib/plugins' ;
module .exports = {
webServer : {
command : 'node ${JSON.stringify(SIMPLE_SERVER_PATH)} ${port}' ,
port : $ { port } ,
} ,
_plugins : [
webServer ( {
command : 'node ${JSON.stringify(SIMPLE_SERVER_PATH)} ${port + 1}' ,
url : 'http://localhost:${port + 1}/port'
} )
]
} ;
` ,
2022-04-29 01:08:10 +03:00
} , undefined , { DEBUG : 'pw:webserver' } ) ;
expect ( result . exitCode ) . toBe ( 0 ) ;
expect ( result . passed ) . toBe ( 1 ) ;
} ) ;
} ) ;
2022-06-11 00:47:29 +03:00
test ( 'should treat 3XX as available server' , async ( { runInlineTest } , { workerIndex } ) = > {
2023-01-21 05:24:15 +03:00
const port = workerIndex * 2 + 10500 ;
2022-06-11 00:47:29 +03:00
const result = await runInlineTest ( {
'test.spec.ts' : `
2023-02-15 06:20:56 +03:00
import { test , expect } from '@playwright/test' ;
2022-06-11 00:47:29 +03:00
test ( 'pass' , async ( { } ) = > { } ) ;
` ,
'playwright.config.ts' : `
module .exports = {
webServer : {
command : 'node ${JSON.stringify(SIMPLE_SERVER_PATH)} ${port}' ,
url : 'http://localhost:${port}/redirect' ,
}
} ;
` ,
} , { } , { DEBUG : 'pw:webserver' } ) ;
expect ( result . exitCode ) . toBe ( 0 ) ;
expect ( result . passed ) . toBe ( 1 ) ;
expect ( result . output ) . toContain ( '[WebServer] listening' ) ;
expect ( result . output ) . toContain ( '[WebServer] error from server' ) ;
} ) ;
2023-02-22 19:09:56 +03:00
test ( 'should check ipv4 and ipv6 with happy eyeballs when URL is passed' , async ( { runInlineTest } , { workerIndex } ) = > {
test . info ( ) . annotations . push ( { type : 'issue' , description : 'https://github.com/microsoft/playwright/issues/20784' } ) ;
const port = workerIndex * 2 + 10500 ;
const result = await runInlineTest ( {
'test.spec.ts' : `
import { test , expect } from '@playwright/test' ;
test ( 'pass' , async ( { } ) = > { } ) ;
` ,
'playwright.config.ts' : `
module .exports = {
webServer : {
command : 'node -e "require(\\' http \ \ ').createServer((req, res) => res.end()).listen(${port}, \\' 127.0 . 0.1 \ \ ')"' ,
url : 'http://localhost:${port}/' ,
}
} ;
` ,
} , { } , { DEBUG : 'pw:webserver' } ) ;
expect ( result . exitCode ) . toBe ( 0 ) ;
expect ( result . passed ) . toBe ( 1 ) ;
expect ( result . output ) . toContain ( 'Process started' ) ;
expect ( result . output ) . toContain ( ` HTTP GET: http://localhost: ${ port } / ` ) ;
expect ( result . output ) . toContain ( 'WebServer available' ) ;
} ) ;
2023-04-27 00:39:42 +03:00
test ( 'should forward stdout when set to "pipe"' , async ( { runInlineTest } , { workerIndex } ) = > {
const port = workerIndex * 2 + 10500 ;
const result = await runInlineTest ( {
'test.spec.ts' : `
import { test , expect } from '@playwright/test' ;
test ( 'pass' , async ( { } ) = > { } ) ;
` ,
'playwright.config.ts' : `
module .exports = {
webServer : {
command : 'node ${JSON.stringify(SIMPLE_SERVER_PATH)} ${port}' ,
port : $ { port } ,
stdout : 'pipe' ,
}
} ;
` ,
} , undefined ) ;
expect ( result . exitCode ) . toBe ( 0 ) ;
expect ( result . passed ) . toBe ( 1 ) ;
expect ( result . output ) . toContain ( '[WebServer] listening' ) ;
2023-05-17 01:46:59 +03:00
expect ( result . output ) . toContain ( '[WebServer] error from server' ) ; // stderr is piped by default
} ) ;
test ( 'should be able to ignore "stderr"' , async ( { runInlineTest } , { workerIndex } ) = > {
const port = workerIndex * 2 + 10500 ;
const result = await runInlineTest ( {
'test.spec.ts' : `
import { test , expect } from '@playwright/test' ;
test ( 'pass' , async ( { } ) = > { } ) ;
` ,
'playwright.config.ts' : `
module .exports = {
webServer : {
command : 'node ${JSON.stringify(SIMPLE_SERVER_PATH)} ${port}' ,
port : $ { port } ,
stderr : 'ignore' ,
}
} ;
` ,
} , undefined ) ;
expect ( result . exitCode ) . toBe ( 0 ) ;
expect ( result . passed ) . toBe ( 1 ) ;
expect ( result . output ) . not . toContain ( 'error from server' ) ;
2023-04-27 00:39:42 +03:00
} ) ;
2023-07-01 02:21:31 +03:00
2023-07-26 01:46:39 +03:00
test ( 'should forward stdout when set to "pipe" before server is ready' , async ( { interactWithTestRunner } ) = > {
2023-07-01 02:21:31 +03:00
test . skip ( process . platform === 'win32' , 'No sending SIGINT on Windows' ) ;
2023-07-26 01:46:39 +03:00
const testProcess = await interactWithTestRunner ( {
2023-07-01 02:21:31 +03:00
'web-server.js' : `
console . log ( 'output from server' ) ;
console . log ( '\\n%%SEND-SIGINT%%' ) ;
setTimeout ( ( ) = > { } , 10000000 ) ;
` ,
'test.spec.ts' : `
import { test , expect } from '@playwright/test' ;
test ( 'pass' , async ( { } ) = > { } ) ;
` ,
'playwright.config.ts' : `
module .exports = {
webServer : {
command : 'node web-server.js' ,
port : 12345 ,
stdout : 'pipe' ,
timeout : 3000 ,
} ,
} ;
` ,
2023-07-26 01:46:39 +03:00
} , { workers : 1 } ) ;
await testProcess . waitForOutput ( '%%SEND-SIGINT%%' ) ;
process . kill ( testProcess . process . pid ! , 'SIGINT' ) ;
await testProcess . exited ;
const result = parseTestRunnerOutput ( testProcess . output ) ;
2023-07-01 02:21:31 +03:00
expect ( result . passed ) . toBe ( 0 ) ;
expect ( result . output ) . toContain ( '[WebServer] output from server' ) ;
expect ( result . output ) . not . toContain ( 'Timed out waiting 3000ms' ) ;
} ) ;