A patch of isEditable of Selenium Core 0.83
日前配合 Selenium 撰寫一個 Web 應用軟體的測試案例,案例中有一句斷言要判定指定的表單輸入欄位是唯讀的 (readonly)。我個人很直覺地使用了 assetrNotEditable
,但測試結果卻是錯的。後來我又試了 assertEditable
、assertAttribute
及 assertNotAttribute
等寫法。始終無法正確而一致地判定輸入欄位的唯讀屬性 (readonly)。
依據參考文件 (Selenium IDE Reference) ,assertEditable/assertNotEditable
的說明,這兩種斷言都是調用 isEditable()
判斷。於是我開啟 selemium-api.js 後搜尋 isEditable
,找出它的源碼內容。結果發現它只判斷輸入控制元件 (input element) 的 disabled 屬性,而未判斷 readonly 屬性。
基本上,disabled 與 readonly 對使用者而言,同樣都令輸入控制元件不能修改內容。兩者的差別主要在於,一個具 disabled 屬性的輸入控制元件,其值不會被遞交回伺服器;而 readonly 屬性的輸入控制元件,其值可能會被遞交回伺服器 (在 W3C HTML Specification 中,這句話的意義等同 "視瀏覽器實作而定")。如下例所示:
<form action="test.php">
<input id="i1" name="i1" value="1" disabled="disabled" />
<input id="i2" name="i2" value="2" readonly="readonly" />
<input id="i3" name="i3" value="3" />
</form>
<?php
echo '<pre>';
print_r($_POST);
echo '</pre>';
?>
因為 i1 具有 disabled 屬性,其值不會被遞交。而i2 僅具有 readonly 屬性,雖然使用者不能修改欄位內容,但其值仍會被遞交。故 test.php 受理後只會收到 i2,i3 兩個輸入控制元件的值。如下所示:
Array ( [i2] => 2 [i3] => 3 )
對使用者而言,這些細節是他們感受不到的。按理說,assertEditable/assertNotEditable
應該會同時判斷輸入控制元件的 disabled 與 readonly 這兩個屬性。可惜 Selenium Core 並不這麼做。雖然不知道原因,不過開發中的案子已經在不少地方使用 readonly (主要是用於資料欄位的"檢視"動作),於是我選擇修改 Selenium Core 的 isEditable
內容。
如果開發團隊習慣使用 readonly 令輸入控制元件之值不可被修改,則 Selenium Core 預設的 assertEditable/assertNotEditable
將造成撰寫測試案例的困擾。可以透過修改或自定 isEditable
動作的方式,加入 readonly 屬性的判斷動作。
selenium-api.js
Selenium.prototype.isEditable = function(locator) {
/**
* Determines whether the specified input element is editable, ie hasn't been disabled.
* This method will fail if the specified element isn't an input element.
*
* @param locator an <a href="#locators">element locator</a>
* @return boolean true if the input element is editable, false otherwise
*/
var element = this.browserbot.findElement(locator);
if (element.value == undefined) {
Assert.fail("Element " + locator + " is not an input.");
}
//return !element.disabled;
return (!element.disabled && !element.getAttribute('readonly'));
};
Firefox 2.x 版不支援 element.readonly
的寫法,要用 W3C DOM 正式的寫法 element.getAttribute('readonly')
才可以。
Selenium IDE 的使用者,可以用 "Option/Selenium Core extensions",以自定測試動作的方式覆蓋掉原先的 isEditable 內容。或者,用 zip 解壓工具,打開 selenium-ide-0.8.7.xpi ,再打開其中的 "chrome/selenium-ide.jar",修改 "/content/selenium/scripts/selenium-api.js" 的內容。改好後再用 zip 壓縮工具包回去。(.xpi/.jar 其實都是 zip 壓縮檔)