工作了不到两周;我终于达到了 Go-DOM 的第一个重要里程碑。
现在,浏览器将在构建 DOM 树时下载并执行远程 JavaScript
。简史
这个项目最初是一个疯狂的想法;看到 Go 和 HTMX 是一个越来越受欢迎的堆栈;
Go 已经拥有测试纯服务器端渲染所需的所有工具。但是,当添加像 HTMX 这样的库时,应用程序的行为是初始 DOM 之间编排的结果;交互元素的属性;到达的 HTTP 端点以及这些端点传送的内容;响应标头和正文。要从用户的角度验证行为,您需要一个浏览器;或者至少是一个行为...与浏览器并不完全不同的测试工具。1
搜索“Go 中的无头浏览器”只会导致建议在无头模式下使用真实浏览器的结果。这种组合有巨大的开销;阻碍快速高效的 TDD 循环。依赖真实的浏览器通常会减慢您的速度而不是加快您的速度。2
于是这个想法就被激发了;用纯 Go 编写一个无头浏览器作为 Web 应用程序的测试工具;
首先要解决的不确定性是 HTML 的解析;以及脚本执行。我很快就做到了; 2天内解决这两个问题。我有一个非常基本的 HTML 解析器;我还将 v8 集成到代码库中3
并使 Go 对象可以被 JavaScript 代码访问。HTML 解析器后来被删除,因为 go x/net/html 已经实现了 HTML 解析器;处理 HTML 解析的所有怪癖。解析格式良好的文档并不是一个非常难解决的问题。它可以优雅地处理格式错误的 HTML,但在这方面却变得棘手。
过了一段时间,我还设法让内联
脚本执行在正确的时刻运行;即当元素实际连接到 DOM 时执行脚本,而不是在解析完整的 HTML 之后执行。处理 HTTP 请求
能够使用内联脚本处理 HTML 文档之后;下一步是实际从源下载
脚本。这就需要集成一个HTTP层;以便浏览器自行获取内容;而不是被灌输内容。http.Client 还允许您使用 http.RoundTripper 接口控制实际的传输层。通常你会启动一个服务器;它将侦听 TCP 端口上的请求。在这种情况下,TCP 充当传输层;但本身与 HTTP 请求的处理无关。由于 Go 中标准 HTTP 堆栈的简单性;整个 HTTP 服务器由单个函数 func Handle(http.ResponseWriter, *http.Request) 表示。
无头浏览器可以完全绕过 TCP 堆栈的开销,并使用自定义的 RoundTripper 直接调用此函数。
现在浏览器可以执行HTTP请求,但浏览器代码本身不知道HTTP层被绕过的事实。随之而来的是在 DOM 解析期间下载脚本的能力。
示例代码
让我们探索一个简单的测试,就像它现在在代码库中一样(代码使用 Ginkgo 和 Gomega,恕我直言,这是一个有点被忽视的组合)
首先,测试创建一个简单的 HTTP 处理程序,该处理程序提供两个端点:/index.html 和 /js/script.js。
It("Should download and execute script from script tags", func() { // Setup a server with test content server := http.NewServeMux() server.HandleFunc( "GET /index.html", func(res http.ResponseWriter, req *http.Request) { res.Write( []byte( `<script src="/js/script.js"></script>Hello, World!`, ), ) }, ) server.HandleFunc( "GET /js/script.js", func(res http.ResponseWriter, req *http.Request) { res.Header().Add("Content-Type", "text/javascript") res.Write([]byte(`var scriptLoaded = true`)) }, ) // ...
此处的目的只是验证脚本是否已执行。为此,脚本会产生一个可观察到的副作用:它在全局范围内设置一个值。
要验证脚本是否已执行,只需检查全局范围,这是通过从测试本身执行临时 JavaScript 来完成的;验证表达式的结果。
创建浏览器、加载索引文件并验证观察到的副作用的代码
browser := ctx.NewBrowserFromHandler(server) Expect(browser.OpenWindow("/index.html")).Error().ToNot(HaveOccurred()) Expect(ctx.RunTestScript("window.scriptLoaded")).To(BeTrue())
测试执行也相当快。测试套件中涉及 JavaScript 执行的部分目前由 32 个测试组成,运行时间为 23 毫秒。
下一个里程碑是集成 HTMX。
由于该项目最初是在尝试验证 HTMX 应用程序时构思的,因此合理的下一个目标是支持这种情况。一个简单的 HTMX 应用程序,带有一个按钮和一个计数器,按下按钮时计数器会增加。
- AnXMLHttpRequest 实现需要就位。为此,工作正在进行中。
- XPathEvaluator。我相信一开始就可以填充。
- 事件传播。现在仅发出 DOMContentLoaded 和 load 事件。元素需要支持更多的事件;比如点击;以及触发它们的方法。
- 这可能还需要正确的事件捕获和冒泡。
进而 ...
接下来是更高级的用户交互;正确的表单处理,例如,输入手线(例如,在 字段中按 enter 提交表单。这通常还涉及某种 URL 重定向;这驱动了对历史对象等的需求.
集成外部站点
具有控制传输层的能力;我们可以提供具有独特能力的测试;我们可以模拟系统在运行时依赖的外部站点。例如,对于给定的主机名,测试可以提供另一个模拟行为的 Go HTTP 处理程序。
最明显的例子是使用外部身份提供商。该测试可以模拟登录流程的行为;不必强迫您在外部系统中创建虚拟帐户,由于外部系统中断而导致测试失败,或者由于身份提供商引入的 2FA 或验证码而根本无法自动化该过程。
另一个用例是使用 API 密集型库,例如地图库,这会产生使用成本。模拟外部站点,以免因运行测试套件而收到额外费用。
可用性胜于兼容性
创建 100% 符合 Whatwg 标准的实现是一项艰巨的任务;直到我真正开始阅读 Whatwg 规范的部分内容之前,我并没有完全理解其范围。目标是创建一个工具帮助为 Web 应用程序编写测试。完全兼容是一个长期目标;但在项目达到某种程度的可用性之前,我会开始填补漏洞。
因此;在实际应用中更可能使用的功能更有可能被优先考虑。指向给出错误结果的实际测试的功能请求可能会被优先考虑。 实施特定标准的功能请求可能会被拒绝。
传播这个词
我相信这对于许多开发人员来说都是一个非常有用的工具,所以如果您阅读了本文,请让您的同事知道它的存在。到目前为止,这只是一个业余时间项目,目前我有很多空闲时间;但情况不会永远如此。
如果你想现场观看,请传播出去......
也许您甚至会赞助这个?您有一家使用 Go 构建 Web 应用程序的大公司吗?欢迎联系我。
在这里找到项目:https://github.com/stroiman/go-dom
-
如果您成功地听到了对 BBC 流行广播剧的致敬,那就太好了。 ↩
-
这是基于个人经验。由于快速的反馈周期,正确执行 TDD 会加快你的速度。真实浏览器的开销往往会让您在生产代码之后编写测试;失去了快速测试套件为您提供的反馈循环的好处。 ↩
-
v8go 项目已经奠定了基础。然而;并非 v8 的所有功能都暴露给 Go 代码;包括嵌入本机对象的必要功能。我能够将它们添加到单独的叉子中;这仍然是 WIP。 ↩
以上是Go-DOM - 重大里程碑的详细内容。更多信息请关注PHP中文网其他相关文章!

Golangisidealforbuildingscalablesystemsduetoitsefficiencyandconcurrency,whilePythonexcelsinquickscriptinganddataanalysisduetoitssimplicityandvastecosystem.Golang'sdesignencouragesclean,readablecodeanditsgoroutinesenableefficientconcurrentoperations,t

Golang在并发性上优于C ,而C 在原始速度上优于Golang。1)Golang通过goroutine和channel实现高效并发,适合处理大量并发任务。2)C 通过编译器优化和标准库,提供接近硬件的高性能,适合需要极致优化的应用。

选择Golang的原因包括:1)高并发性能,2)静态类型系统,3)垃圾回收机制,4)丰富的标准库和生态系统,这些特性使其成为开发高效、可靠软件的理想选择。

Golang适合快速开发和并发场景,C 适用于需要极致性能和低级控制的场景。1)Golang通过垃圾回收和并发机制提升性能,适合高并发Web服务开发。2)C 通过手动内存管理和编译器优化达到极致性能,适用于嵌入式系统开发。

Golang在编译时间和并发处理上表现更好,而C 在运行速度和内存管理上更具优势。1.Golang编译速度快,适合快速开发。2.C 运行速度快,适合性能关键应用。3.Golang并发处理简单高效,适用于并发编程。4.C 手动内存管理提供更高性能,但增加开发复杂度。

Golang在Web服务和系统编程中的应用主要体现在其简洁、高效和并发性上。1)在Web服务中,Golang通过强大的HTTP库和并发处理能力,支持创建高性能的Web应用和API。2)在系统编程中,Golang利用接近硬件的特性和对C语言的兼容性,适用于操作系统开发和嵌入式系统。

Golang和C 在性能对比中各有优劣:1.Golang适合高并发和快速开发,但垃圾回收可能影响性能;2.C 提供更高性能和硬件控制,但开发复杂度高。选择时需综合考虑项目需求和团队技能。

Golang适合高性能和并发编程场景,Python适合快速开发和数据处理。 1.Golang强调简洁和高效,适用于后端服务和微服务。 2.Python以简洁语法和丰富库着称,适用于数据科学和机器学习。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能

SublimeText3 英文版
推荐:为Win版本,支持代码提示!

MinGW - 适用于 Windows 的极简 GNU
这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。