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("- "))
+ res.Write([]byte(req.Method))
+ res.Write([]byte("
- "))
+ res.Write(body)
+ res.Write([]byte("
- "))
+ res.Write([]byte(req.URL.RawQuery))
+ res.Write([]byte("
"))
+ default:
+ h.fs.ServeHTTP(res, req)
+ }
+}