關於事物如何形成的思考
此文件先前位於 wiki 上
簡介
這是一個進行中的工作。歡迎隨時新增您知道或記得的事情。
自動化原子是如何產生的?
在 2012-04-04,jimevans 在 #selenium IRC 頻道上問道
「我想問你的是關於自動化原子的歷史。我記得它們似乎是完全成形的,彷彿從宙斯頭部蹦出來一樣,但我確信情況並非如此。你能否幫我回憶一下這個概念是如何產生的?」
然後 simonstewart 開始告訴我們一個有趣的小故事
當然。我們坐好了嗎?那麼我就開始了。(英國笑話,在這裡)
想像一下波浪線,螢幕逐漸溶解,我們被帶回到 selenium 和 webdriver 還是不同專案的時候。在專案合併之前,webdriver 中有非常多相似的程式碼。相似,但沒有共享。Firefox 驅動程式是用 JS 寫的。IE 驅動程式主要用 C++ 寫的。Chrome 驅動程式主要用 JS 寫的,但與 Firefox 驅動程式的 JS 不同。而 HtmlUnit 則是獨特的。
然後我們將 Selenium Core 加入其中。更多基本上做著相同事情的 JS。
在 Google 內部,我即將成為瀏覽器自動化團隊的 TL。並將我們自己的框架也納入其中。這個框架是用 JS 寫的,曾經以 Core 為基礎,然後才走上自己的道路。
所以:多個程式碼庫,大量 JS 做著或多或少相同的事情。以及大量的錯誤。邊緣情況下行為的奇怪不匹配。
*發抖*
所以我稍微思考了一下。(我知道很危險)這個想法是從所有三個框架(Core、WebDriver 和 Google 工具)中提取「最佳」程式碼。將它們分解成可以共享的程式碼。「瀏覽器自動化的最小、不可分割的單位」。
或者簡稱為「原子」。
這些可以用作一切的基礎。瀏覽器之間行為一致。以及 API。另一個重點是 webdriver 和 core 中的 JS 程式碼是有機成長的。這是一種禮貌的說法,表示「我寧願永遠不再編輯它」。這是一種更禮貌的說法,表示它在某些地方品質可疑。
所以:高品質很重要。而且我希望程式碼被分解成模組。因為編輯一個 1 萬行程式碼的文件不是一個好主意。
在 Google 內部,我們有一個名為 Closure 的函式庫。它不僅允許模組化,還可以通過編譯將模組「反正規化」為單個文件。而且我知道它即將開源。所以我們開始在 Google 程式碼庫中建構這個函式庫。(在那裡我們可以訪問未發布的函式庫、程式碼審查工具和我們驚人的測試基礎設施)。使用 Closure Library。
「dom.js」可能是我寫的第一個文件。(我們可以檢查)。Greg Dennis 和 Jason Leyba 也加入了這個樂趣。從那時起,原子就不斷增長。
從技術上講,我們應該將「javascript/atoms」之外的任何東西稱為分子。但是這樣我們就不能說我們有原子驅動程式。並使用 50 年代的意象來描述它們。
*嘆氣*
jimevans 回覆:「分子驅動程式?」
然後 simonstewart 總結道
確實 :) 這個想法是原子是最低層級。然後我們組合原子,使其符合「javascript/{selenium,webdriver}-atoms」中 WebDriver 或 RC API。然後根據需要吸入這些。
一個關於瘋狂樂趣的故事
Simon Stewart
所以,讓我們回到專案的最初
當時只有我一個人
(也就是 webdriver 專案,而不是 selenium 本身)
我知道我想涵蓋多種不同的語言,所以想要一個可以與所有這些語言一起工作的建構工具
也就是說,它沒有內建對某種語言的偏好,以至於使用其他語言變得痛苦
ant 偏向 Java。Maven 也是。
nant 和 msbuild 偏向 .net。
rake,另一方面,對任何東西的支援都不太好
但是,這是關鍵,任何有效的 rake 腳本也是有效的 ruby 程式
可以擴展 rake 來建構任何東西
所以:就用 rake 了
最初的 rake 文件非常小且易於管理
但隨著專案的成長,Rakefile 也隨之成長
直到只有一個人(我)可以處理它,即使那樣也很不穩定
所以,與其讓專案無法建構,不如我提取了一些輔助方法來完成一些繁重的工作
這使 Rakefile 再次變得容易理解
但專案一直。變得。更大
而且 Rakefile 變得越來越難理解
當時,我在 Google 工作,他們有一個很棒的建構系統
Google 的系統是宣告式的,並且可以跨多種不同的語言一致地工作
而且,最重要的是,它將建構從單個文件分解成小片段
我問了 Google 的 OSS 夥伴是否可以開源建構語法,他們開了綠燈
所以我們將該建構語法分層到 selenium 程式碼庫中
做了一個小小的更改(我們處理字典參數)
但該語法仍然位於 rake 之上
至今,仍然如此
而且有一個問題
那就是 rake 是單線程的
所以我們的建構被限制為串行執行
我們可以使用「multitask」類型來改進事情,但當我嘗試時,事情變得非常混亂,非常快
所以,我們的下一個障礙是 crazyfun.rb 很慢:我們需要更快
這意味著需要重寫 crazyfun
我最熟悉 Java
所以,我用 Java 試做了一個新版本,它可以處理 Java 和 JS 編譯
它顯著更快
但是,這也很重要,它只是一個試做版本
這個程式碼被設計為可拋棄式的。
現在事情已經被證明可行,我真的很想做一個乾淨的實作
但我很矛盾
我應該「完成」新的、非常快速的 crazyfun java,使其足以取代 ruby 版本嗎?
一個關於驅動程式執行檔的故事
jimevans
noob_einsteinsfo:好的,說故事時間到了。我們坐好了嗎?那麼我們就開始了。
noob_einsteinsfo:回到我剛開始參與這個專案的時候(大約 2010 年),所有瀏覽器的驅動程式都是由專案建構和維護的。
當時,這意味著 IE、Firefox 和 Chrome。
所有這些驅動程式都作為 selenium standalone server 的一部分打包,並且也與各種語言綁定一起打包。
這是一個有意識的決定,這樣如果有人在本地運行,就不需要在機器上安裝 Java 運行時,僅僅為了自動化特定的瀏覽器。
有兩個因素導致了瀏覽器驅動程式作為獨立執行檔的開發。
作為一個簡短的題外話,請記住 webdriver 的理念是使用「最適合」特定瀏覽器的機制來自動化瀏覽器。
對於 IE,這意味著使用 COM 介面;對於當時的 Firefox,這意味著使用瀏覽器擴展;對於 Chrome,也意味著瀏覽器擴展。
所以這意味著 IE 驅動程式是用 C++ 開發為 DLL,由語言綁定加載,並通過語言提供的任何本機程式碼機制(Java 的 JNI、.NET 的 P/Invoke、Python 的 ctypes 等)進行通信。
這也意味著 Firefox 驅動程式被開發為瀏覽器擴展,打包在各種語言綁定內部,並被提取出來,在 Firefox 的設定檔中使用。
正如我所說,IE 驅動程式被實作為 DLL,使用不同語言綁定的不同機制進行加載和通信。
問題是,這些特定於語言的機制中的每一個都有不同的加載/卸載語義。
例如,Ruby 在將 DLL 加載到記憶體後永遠不會調用 Windows FreeLibrary API,這使得多個實例非常具有挑戰性。
然而,「*進程*」語義,例如,在 OS 上啟動、停止和管理進程的生命週期,無論是什麼 OS,在所有語言中都非常相似。
因此,當 IE 驅動程式重寫在 2010 年完成時,開發團隊(我)決定將其做成一個單獨的執行檔,以便無論使用什麼語言綁定,加載/卸載語義都可以保持一致。
與此同時,chromium 團隊決定效仿 opera 的做法,為 chrome 提供驅動程式實作。
一個他們將在未來開發、增強和維護的實作,從而減輕 selenium 專案維護 chrome 驅動程式的負擔。
XgizmoX
並且那個驅動程式是瀏覽器的一部分嗎?
jimevans
XgizmoX:不完全是,但我相信 chrome 本身可能內建了一些智慧,知道它何時通過 chromedriver 進行自動化。Google 的某個人會更適合回答這個問題。
無論如何,了解到共享函式庫 (.dll/.so/.dynlib) 加載語義的差異,chromium 團隊(在我的鼓勵下)決定將他們的 chromedriver 實作作為一個單獨的執行檔發布。
快進幾年,你開始看到將 webdriver 變成 w3c 標準的努力。
與 w3c 合作的一個工作組創建了一個規範(仍在進行中,但第一版即將完成),該規範編纂了 webdriver 的行為,以及瀏覽器應如何響應其方法。此外,它標準化了用於在語言綁定和特定瀏覽器的驅動程式之間進行通信的協議。
我再怎麼強調這有多重要和具有開創性都不為過。
因為 w3c 和其中的 webdriver 工作組由瀏覽器供應商本身的代表組成,這確保了解決方案將直接得到瀏覽器供應商的支持。
Mozilla 為 Firefox 創建了他們的 webdriver 實作 (geckodriver)。
在保持語言綁定的正確語義的同時,分發該瀏覽器驅動程式最有效率的機制是作為一個單獨的執行檔發布。
請注意,這是對 geckodriver 架構的嚴重過度簡化;實際的執行檔充當一個相對薄的墊片,從規範的線協議轉換為它們的內部 marionette 協議
但重點仍然存在。
無論如何,關於瀏覽器供應商提供的驅動程式實作,情況目前正在發展。Microsoft 為 Edge 提供了一個,Apple 為 Safari(10 及更高版本)提供了一個,chromium 團隊(主要由 Google 員工組成)為 Chrome 提供了一個,現在 Mozilla 為 Firefox 提供了一個。
鑑於舊版 Firefox 驅動程式在未來的有限實用性,將其分解為單獨的執行檔將是浪費精力。
尤其如此,因為通常由執行檔處理的所有通信位(偵聽和響應來自語言綁定的 http 請求)都完全由瀏覽器擴展處理。 \
舊版 Firefox 驅動程式完全沒有必要成為一個單獨的執行檔。
此外,使其獨立於語言運行時將是一項重要的工作
(因為一個 .NET 商店可能會合理地反對被要求安裝,例如,Java 運行時,僅僅為了自動化 Firefox)
所以從歷史角度來看,noob-einsteinsfo,這就是為什麼單獨的執行檔已成為常態的總體原因,以及為什麼這種範例沒有擴展到包含舊版 Firefox 驅動程式。
這樣有道理嗎?
好的。
現在。
關於 geckodriver。
geckodriver 的故事與前面提到的 w3c webdriver 規範的狀態密切相關。
規範的第一級大部分已完成,儘管花了數年的努力才達到這個目標。
許多非常聰明的人(其中包括 AutomatedTester)付出了巨大的努力,將 webdriver 開源軟體 (OSS) 專案的初始文件塑造成適當的規範語言,瀏覽器供應商或其他實作者可以解釋並將其轉化為可操作的東西。
在開始 geckodriver (nee marionette) 專案時,Mozilla 決定將他們的實作基於規範,並且僅基於規範,而不是遵循 OSS 實作。
這造成了一個雞生蛋蛋生雞的問題,因為在規範語言未完成時,就無法實作它。
僅在最近六個月左右,關於高級用戶互動 API(Java 和 .NET 中的 Actions 類)的語言才變得足夠穩健以實際實作。
因此,這是目前 geckodriver 中功能缺失的最大部分。它無法通過規範實作,因此尚未實作。
我確實知道,AutomatedTester 和他的團隊將完成並提供該實作作為高度優先事項。
至於為什麼 geckodriver 是強制性的,並且是 3.x 中自動化 Firefox 的預設實作,這也歸結於 Mozilla 做出的一些決定。
TheSchaf
所以我猜別無選擇,只能在缺少所需功能的情況下使用舊版 FF
WhereIsMySpoon
TheSchaf:如果您需要這些功能,是的
或使用另一個瀏覽器
TheSchaf
嗯,moveTo 和 sendKeys 應該是很基本的 :p
jimevans
TheSchaf:element.sendKeys 工作正常。會壞掉的是 Actions.sendKeys。
在 Firefox 四十幾版(我記不清確切版本)中,添加了一個功能,阻止了未經 Mozilla 安全團隊簽名的瀏覽器擴展。
還記得舊版 Firefox 驅動程式是作為瀏覽器擴展建構的嗎?好吧,在瀏覽器的該功能啟用後,舊版驅動程式無法被瀏覽器加載。
現在,對於幾個版本的 Firefox,可以禁用瀏覽器的此功能,並允許繼續加載未簽名的擴展。
並且 selenium 做到了這一點,通過在啟動 Firefox 時綁定創建的匿名設定檔中使用的設定。
直到 Firefox 48,在那時,不再可能禁用加載未簽名的擴展。
在那時,geckodriver 是唯一的出路。
現在,還有兩個小點,然後我就結束說故事時間了。
首先,由於舊版驅動程式擴展的功能性質,不可能讓它通過 Mozilla 安全團隊的認證過程。
我們問了,被拒絕了,並被告知永遠不會發生,就這樣。
這完全合理,因為該擴展所做的事情是一個足夠大的安全漏洞,可以讓整個卡車隊通過。
其次,事實證明,實際上可能有一種方法可以私下簽署舊版擴展,以便 Firefox 48 及更高版本可以私下加載和使用它。
這仍然不是一個理想的方法,因為我們的開源開發人員團隊不可能比 Mozilla 的開發團隊更了解如何自動化 Firefox,而 Mozilla 的開發團隊才是最初創建瀏覽器的人。
我完全理解 geckodriver 不具備舊版實作的完整功能對等性所帶來的挫敗感,尤其是在感覺自己被迫遷移到它的時候。
對於該決定向 selenium 專案發怒是完全找錯了方向。
然而,在開始說 Mozilla 決定的壞話之前,請了解 Mozilla 有幾個人一直在參與這個專案,其中一些人就在這個頻道中(AutomatedTester、davehunt,僅舉兩個例子)。
我確信我已經忽略或錯誤描述了這些事情的一些歷史細節,我很樂意被糾正。畢竟我老了,記憶力不如以前了。
但是,我的朋友們,這就是(不太簡短的)歷史,說明了為什麼我們有單獨的驅動程式執行檔,以及為什麼 geckodriver 是前進的方向,以及為什麼即使在功能有所欠缺的情況下,遷移到它是必要的。
jimevans 覺得自己已經成為 webdriver 專案的非官方歷史學家
文字記錄: https://botbot.me/freenode/selenium/2016-12-21/?msg=78265715&page=6
我們發行版本的非正式命名(按 IRC 頻道主題)
Selenium 2 beta 3 「下一代瀏覽器版本」現已發布 - http://bit.ly/i9bkC2
Selenium 2 RC1 「grid 版本」現已發布 - http://bit.ly/jgZxW8
Selenium 2 RC2 「更好用的版本」現已發布 - http://bit.ly/mJJX1z
Selenium RC3 - 「下一個是『大』版本」發布 - http://bit.ly/kpiACx
Selenium 2.0 Final 向毫無戒心的群眾發布
Selenium 2.1.0 現已發布(是的,現在甚至適用於 maven 用戶)
Selenium 2.2.0 現已發布(在 nuget 中...是的,甚至適用於 maven)
Selenium 2.3.0 現已發布。一個新的傳統!
Selenium 2.4.0 已發布 – 東西改變了,但還沒有部落格文章
Selenium 2.5.0。嗯嗯。培根。
Selenium 2.6.0 現已發布。切換並在汽車保險上節省 15% 或更多
Selenium 2.7.0 的 Ruby 綁定首先發布(至少在 twitter 上)。Jari 真是個機器…
Selenium 2.8.0 現已發布 – 一天前的培根仍然是培根
可惜我們遺失了 IRC 日誌…
Selenium 2.22:為期一個月的每週發行版本終於來了!
Selenium 2.23:「現在有了驚人的東西!」等等。什麼?現在?!
Selenium 2.24:現在有了更多,嗯,東西?
Selenium 2.25:追蹤良好
2.26 已發布!
Selenium 2.27 已發布,修復了 Firefox 17 的問題。趁熱享用!
(沒有 2.28 主題更新)code.google.com/p/selenium 鏡像到 github.com/seleniumHQ/selenium - 我們現在在 git 上了!
2.29.0 現已發布!第一個帶有 FF18 支援的 git 版本!
砰!2.31 發布,甚至帶有 Firefox 19 的原生事件支援。
「相關性並不意味著因果關係」2.32.0 發布,帶有 Firefox 20 支援。
美國政府重新開放了!讓我們用新發布的 2.36 來慶祝,它帶有 FF24 支援
2.40 真是太棒了,自動化了很多,修復了很多問題
2.41 - 最後一個「支援」ie6 的版本
2.45.0 - 發布,帶有 FF36 支援
2.46.0 - 發布,帶有 FF38 支援
2.47.0 - 發布,帶有 Edge 支援
2.48.0 - 發布,在所有語言中都帶有 Marionette 支援
2.49.0 發布 - 帶有 FF 43 支援
2.50.0 發布 - 「全他媽的是邊緣情況!」 - D.W-H
2.51.0 發布 - 「全他媽的是邊緣情況!」 - D.W-H
2.52.0 發布 - 現在您可以禁用「所有他媽的邊緣情況!」
2.53.0 最終 RC 版本
3.0 聖誕節版本!FF48 現在需要 GeckoDriver
3.6 「不在星期五發布」版本