diff --git a/public/dynamic_scripts/index.html b/public/dynamic_scripts/index.html new file mode 100644 index 0000000..34f905a --- /dev/null +++ b/public/dynamic_scripts/index.html @@ -0,0 +1,9 @@ + + + +
+ diff --git a/public/dynamic_scripts/script.js b/public/dynamic_scripts/script.js new file mode 100644 index 0000000..e4df4a2 --- /dev/null +++ b/public/dynamic_scripts/script.js @@ -0,0 +1,3 @@ +(() => { + document.getElementById('product').innerText = 'Keemun'; +})(); diff --git a/public/form/get.html b/public/form/get.html new file mode 100644 index 0000000..c51dcb7 --- /dev/null +++ b/public/form/get.html @@ -0,0 +1,10 @@ + + +
+ + + + +
+ + diff --git a/public/form/post.html b/public/form/post.html new file mode 100644 index 0000000..75abf2b --- /dev/null +++ b/public/form/post.html @@ -0,0 +1,10 @@ + + +
+ + + + +
+ + diff --git a/public/location_write/index1.html b/public/location_write/index1.html new file mode 100644 index 0000000..a1eaec5 --- /dev/null +++ b/public/location_write/index1.html @@ -0,0 +1,5 @@ + + +
1
+ + diff --git a/public/location_write/index2.html b/public/location_write/index2.html new file mode 100644 index 0000000..332bf8e --- /dev/null +++ b/public/location_write/index2.html @@ -0,0 +1,5 @@ + + +
2
+ + diff --git a/public/location_write/index3.html b/public/location_write/index3.html new file mode 100644 index 0000000..fbcd22e --- /dev/null +++ b/public/location_write/index3.html @@ -0,0 +1,5 @@ + + +
3
+ + diff --git a/public/location_write/index4.html b/public/location_write/index4.html new file mode 100644 index 0000000..357d334 --- /dev/null +++ b/public/location_write/index4.html @@ -0,0 +1,4 @@ + + +
4
+ diff --git a/puppeteer/dynamic_scripts.js b/puppeteer/dynamic_scripts.js new file mode 100644 index 0000000..3c5b891 --- /dev/null +++ b/puppeteer/dynamic_scripts.js @@ -0,0 +1,45 @@ +// Copyright 2023-2024 Lightpanda (Selecy SAS) +// +// 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. +'use scrict' + +import puppeteer from 'puppeteer-core'; + +const browserAddress = process.env.BROWSER_ADDRESS ? process.env.BROWSER_ADDRESS : 'ws://127.0.0.1:9222'; +const baseURL = process.env.URL ? process.env.URL : 'http://127.0.0.1:1234' + +// use browserWSEndpoint to pass the Lightpanda's CDP server address. +const browser = await puppeteer.connect({ + browserWSEndpoint: browserAddress, +}); + +// The rest of your script remains the same. +const context = await browser.createBrowserContext(); +const page = await context.newPage(); + +await page.goto(baseURL + '/dynamic_scripts/index.html');; + +await page.waitForFunction(() => { + const products = document.querySelector('#product'); + return products.textContent.length > 0; +}, {timeout: 1000}); + +const product = await page.evaluate(() => { return document.querySelector('#product').textContent; }); +if (product !== 'Keemun') { + console.log(res); + throw new Error("invalid product"); +} + +await page.close(); +await context.close(); +await browser.disconnect(); diff --git a/puppeteer/form.js b/puppeteer/form.js new file mode 100644 index 0000000..0404982 --- /dev/null +++ b/puppeteer/form.js @@ -0,0 +1,72 @@ +// Copyright 2023-2024 Lightpanda (Selecy SAS) +// +// 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. +'use scrict' + +import puppeteer from 'puppeteer-core'; + +const browserAddress = process.env.BROWSER_ADDRESS ? process.env.BROWSER_ADDRESS : 'ws://127.0.0.1:9222'; +const baseURL = process.env.URL ? process.env.URL : 'http://127.0.0.1:1234' + +// use browserWSEndpoint to pass the Lightpanda's CDP server address. +const browser = await puppeteer.connect({ + browserWSEndpoint: browserAddress, +}); + +// The rest of your script remains the same. +const context = await browser.createBrowserContext(); +const page = await context.newPage(); + +await testForm(page, '/form/get.html', { + method: 'GET', + body: '', + query: 'h1=v1&h3=v3&favorite+drink=tea', +}); + +await testForm(page, '/form/post.html', { + method: 'POST', + body: 'h1=v1&h3=v3&favorite+drink=tea', + query: '', +}); + + +await context.close(); +await browser.disconnect(); + + +async function testForm(page, url, expected) { + await page.goto(baseURL + url);; + + await page.waitForFunction(() => { + const p = document.querySelector('#method'); + return p.textContent != ''; + }, {timeout: 4000}); + + const method = await page.evaluate(() => { return document.querySelector('#method').textContent; }); + if (method !== expected.method) { + console.log(method); + throw new Error("invalid method"); + } + + const body = await page.evaluate(() => { return document.querySelector('#body').textContent; }); + if (body !== expected.body) { + console.log(body); + throw new Error("invalid body"); + } + + const query = await page.evaluate(() => { return document.querySelector('#query').textContent; }); + if (query !== expected.query) { + console.log(query); + throw new Error("invalid query"); + } +} diff --git a/puppeteer/location_write.js b/puppeteer/location_write.js new file mode 100644 index 0000000..4f803ea --- /dev/null +++ b/puppeteer/location_write.js @@ -0,0 +1,39 @@ +// Copyright 2023-2024 Lightpanda (Selecy SAS) +// +// 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. +'use scrict' + +import puppeteer from 'puppeteer-core'; + +const browserAddress = process.env.BROWSER_ADDRESS ? process.env.BROWSER_ADDRESS : 'ws://127.0.0.1:9222'; +const baseURL = process.env.URL ? process.env.URL : 'http://127.0.0.1:1234' + +// use browserWSEndpoint to pass the Lightpanda's CDP server address. +const browser = await puppeteer.connect({ + browserWSEndpoint: browserAddress, +}); + +// The rest of your script remains the same. +const context = await browser.createBrowserContext(); +const page = await context.newPage(); + +await page.goto(baseURL + '/location_write/index1.html');; +await page.waitForFunction(() => { + const p = document.querySelector('#page'); + return p.textContent == '4'; + +}, {timeout: 2000}); + +await page.close(); +await context.close(); +await browser.disconnect(); diff --git a/runner/main.go b/runner/main.go index b006f4c..ed1f725 100644 --- a/runner/main.go +++ b/runner/main.go @@ -102,6 +102,9 @@ func run(ctx context.Context, args []string, stdout, stderr io.Writer) error { {Bin: "node", Args: []string{"puppeteer/links.js"}, Env: []string{"URL=http://127.0.0.1:1234/campfire-commerce/"}}, {Bin: "node", Args: []string{"puppeteer/click.js"}}, {Bin: "node", Args: []string{"puppeteer/wait_for_network.js"}}, + {Bin: "node", Args: []string{"puppeteer/dynamic_scripts.js"}}, + {Bin: "node", Args: []string{"puppeteer/location_write.js"}}, + {Bin: "node", Args: []string{"puppeteer/form.js"}}, {Bin: "node", Args: []string{"playwright/connect.js"}}, {Bin: "node", Args: []string{"playwright/cdp.js"}, Env: []string{"RUNS=2"}}, {Bin: "node", Args: []string{"playwright/click.js"}}, @@ -161,11 +164,11 @@ func runtest(ctx context.Context, t Test) error { // run the local http server func runhttp(ctx context.Context, addr, dir string) error { - handler := http.FileServer(http.Dir(dir)) + fs := http.FileServer(http.Dir(dir)) srv := &http.Server{ Addr: addr, - Handler: handler, + Handler: Handler{fs: fs}, BaseContext: func(net.Listener) context.Context { return ctx }, @@ -201,3 +204,29 @@ func env(key, dflt string) string { return val } + +type Handler struct { + fs http.Handler +} + +func (h Handler) ServeHTTP(res http.ResponseWriter, req *http.Request) { + switch req.URL.Path { + case "/form/submit": + defer req.Body.Close() + body, err := io.ReadAll(req.Body) + if err != nil { + panic(err) + } + + res.Header().Add("Content-Type", "text/html") + res.Write([]byte("")) + default: + h.fs.ServeHTTP(res, req) + } +}