Go-DOM - 重大里程碑
工作了不到兩週;我終於達到了 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( `<html><head><script src="/js/script.js"></script></head><body>Hello, World!</body>`, ), ) }, ) 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中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

OpenSSL,作為廣泛應用於安全通信的開源庫,提供了加密算法、密鑰和證書管理等功能。然而,其歷史版本中存在一些已知安全漏洞,其中一些危害極大。本文將重點介紹Debian系統中OpenSSL的常見漏洞及應對措施。 DebianOpenSSL已知漏洞:OpenSSL曾出現過多個嚴重漏洞,例如:心臟出血漏洞(CVE-2014-0160):該漏洞影響OpenSSL1.0.1至1.0.1f以及1.0.2至1.0.2beta版本。攻擊者可利用此漏洞未經授權讀取服務器上的敏感信息,包括加密密鑰等。

在BeegoORM框架下,如何指定模型關聯的數據庫?許多Beego項目需要同時操作多個數據庫。當使用Beego...

後端學習路徑:從前端轉型到後端的探索之旅作為一名從前端開發轉型的後端初學者,你已經有了nodejs的基礎,...

GoLand中自定義結構體標籤不顯示怎麼辦?在使用GoLand進行Go語言開發時,很多開發者會遇到自定義結構體標籤在�...

Go語言中用於浮點數運算的庫介紹在Go語言(也稱為Golang)中,進行浮點數的加減乘除運算時,如何確保精度是�...

Go爬蟲Colly中的Queue線程問題探討在使用Go語言的Colly爬蟲庫時,開發者常常會遇到關於線程和請求隊列的問題。 �...

Go語言中使用RedisStream實現消息隊列時類型轉換問題在使用Go語言與Redis...

本文介紹如何在Debian系統上配置MongoDB實現自動擴容,主要步驟包括MongoDB副本集的設置和磁盤空間監控。一、MongoDB安裝首先,確保已在Debian系統上安裝MongoDB。使用以下命令安裝:sudoaptupdatesudoaptinstall-ymongodb-org二、配置MongoDB副本集MongoDB副本集確保高可用性和數據冗餘,是實現自動擴容的基礎。啟動MongoDB服務:sudosystemctlstartmongodsudosys
