Ai
1 Star 0 Fork 0

nuokwan/chromedp

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
util_test.go 4.74 KB
一键复制 编辑 原始数据 按行查看 历史
Daniel Martí 提交于 2020-01-06 12:59 +08:00 . add an example about reusing a browser
package chromedp
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"strconv"
"testing"
"time"
"github.com/chromedp/cdproto/cdp"
"github.com/chromedp/cdproto/runtime"
)
// dumpJS is a javascript snippet that dumps the passed element node in the
// same text format as cdproto/cdp/Node.Dump.
//
// Used to verify that the DOM tree built by chromedp is the same as what
// chrome itself sees.
//
// Note: written to be "line-by-line equivalent" with Node.Dump's
// implementation.
const dumpJS = `(function dump(n, prefix, indent, nodeIDs) {
if (n === null || typeof n !== 'object') {
return prefix + '<nil>';
}
var s = '';
if (typeof n.localName !== 'undefined') {
s = n.localName;
}
if (s === '' && typeof n.nodeName !== 'undefined') {
s = n.nodeName;
}
if (s === '') {
throw 'invalid node element';
}
if (typeof n.attributes !== 'undefined') {
for (var i = 0; i < n.attributes.length; i++) {
if (n.attributes[i].name.toLowerCase() === 'id') {
s += '#' + n.attributes[i].value;
break;
}
}
}
if (n.nodeType !== 1 && n.nodeType !== 3) {
s += ' <' + [
'Element',
'Attribute',
'Text',
'CDATA',
'EntityReference',
'Entity',
'ProcessingInstruction',
'Comment',
'Document',
'DocumentType',
'DocumentFragment',
'Notation'
][n.nodeType - 1] + '>';
}
if (n.nodeType === 3) {
var v = n.nodeValue;
if (v.length > 15) {
v = v.substring(0, 15) + '...';
}
s += ' ' + JSON.stringify(v);
}
if (n.nodeType === 1 && typeof n.attributes !== 'undefined' && n.attributes.length > 0) {
var attrs = '';
for (var i = 0; i < n.attributes.length; i++) {
if (n.attributes[i].name.toLowerCase() === 'id') {
continue;
}
if (attrs !== '') {
attrs += ' ';
}
attrs += n.attributes[i].name + '=' + JSON.stringify(n.attributes[i].value);
}
if (attrs != '') {
s += ' [' + attrs + ']';
}
}
if (nodeIDs) {
throw 'cannot read element node ID from scripts';
}
if (typeof n.childNodes !== 'undefined' && n.childNodes.length > 0) {
for (var i = 0; i < n.childNodes.length; i++) {
// skip empty #text nodes
if (n.childNodes[i].nodeType === 3 && n.childNodes[i].nodeValue.trim() === '') {
continue;
}
s += '\n' + dump(n.childNodes[i], prefix+indent, indent, nodeIDs);
}
}
return prefix + s;
})(%s, %q, %q, %t);`
const insertJS = `(function(n, typ, id, text) {
var el = document.createElement(typ);
el.id = id;
el.innerText = text;
%s;
})(document.querySelector(%q), %q, %q, %q)`
// test:
// insertBefore
// removeChild
// appendChild
// replaceChild
// prepend
// append
// insertAdjacentElement
func TestNodeOp(t *testing.T) {
t.Parallel()
s := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
fmt.Fprintf(res, `<!doctype html>
<html>
<head>
<title>empty test page</title>
</head>
<body>
<div id="div1">div1 content</div>
</body>
<html>`)
}))
defer s.Close()
ctx, cancel := testAllocate(t, "")
defer cancel()
// get document root
var nodes []*cdp.Node
if err := Run(ctx,
Navigate(s.URL),
WaitVisible(`#div1`),
Nodes(`//*`, &nodes),
Nodes(`document`, &nodes, ByJSPath),
); err != nil {
t.Fatal(err)
}
tests := []struct {
q, expr string
}{
{`body`, `n.insertBefore(el, n.childNodes[0])`},
{`body`, `n.insertBefore(el, n.childNodes[1])`},
{`#div3`, `n.prepend(el)`},
{`#div2`, `n.append(el)`},
{`#div2`, `n.appendChild(el)`},
{`#div3`, `n.removeChild(n.childNodes[0])`},
{`#div2`, `n.insertAdjacentElement('afterend', el)`},
{`body`, `n.insertBefore(el, n.childNodes[0])`},
{`body`, `n.insertBefore(el, n.childNodes[1])`},
{`#div2`, `n.replaceChild(el, n.childNodes[1])`},
}
prev := nodes[0].Dump("", " ", false)
for i, test := range tests {
// modify tree
if err := Run(ctx,
ActionFunc(func(ctx context.Context) error {
id := strconv.Itoa(i + 2)
expr := fmt.Sprintf(insertJS, test.expr, test.q, `div`, `div`+id, `div`+id+` content`)
_, exp, err := runtime.Evaluate(expr).Do(ctx)
if err != nil {
return err
}
if exp != nil {
return exp
}
return nil
}),
); err != nil {
t.Fatal(err)
}
// wait for events to propagate
time.Sleep(5 * time.Millisecond)
tree := nodes[0].Dump("", " ", false)
if prev == tree {
t.Fatalf("test %d expected tree to change (prev == tree)\n-- PREV:\n%s\n-- TREE:\n%s\n--\n", i, prev, tree)
}
// retrieve browser's tree view
var exp string
if err := Run(ctx,
EvaluateAsDevTools(fmt.Sprintf(dumpJS, `document`, "", " ", false), &exp),
); err != nil {
t.Fatal(err)
}
if exp != tree {
t.Errorf("test %d expected tree and node tree do not match:\n-- EXPECTED:\n%s\n-- GOT:\n%s\n--\n", i, exp, tree)
}
prev = tree
// t.Logf("test %d:\n%s\n--\n", i, tree)
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/nuokwan/chromedp.git
git@gitee.com:nuokwan/chromedp.git
nuokwan
chromedp
chromedp
master

搜索帮助