1. 程式人生 > >web自動化測試框架selenium呼叫JavaScript程式碼常用操作解析

web自動化測試框架selenium呼叫JavaScript程式碼常用操作解析

        在做web專案時,通常需要開發一些自動化用例,自動化用例執行可以設定觸發條件,也可以定時執行,在每次程式碼發生變更的情況下,自動觸發自動化用例執行,可以及時檢測修改程式碼是否引入新的問題,提高產品的自信度。在開發web端自動化用例程式碼時,目前大多采用主流的selenium測試框架,selenium框架中的webdriver驅動瀏覽器模擬人的行為對頁面進行操作,開發過程主要可以拆分為以下幾個階段:

        a)、web頁面載入

        b)、定位頁面元素

        c)、操作頁面元素,主要包括文字框輸入、滑鼠移動、滑鼠點選等

        d)、判斷返回結果

        其中最主要的就是 b、c 兩步,首先要定位到對應的元素,然後才能對元素進行操作。在selenium中提供了8中元素定位方式,可以通過元素ID號、標籤名稱、元素name屬性、標籤文字內容、cssselector、xpath等方式進行定位,這8中定位方式基本可以滿足所有的元標籤元素定位需求。

        但是,在實際使用中會發現,使用如上方式進行元素操作經常會遇到如下兩個問題:

        a)、一是程式碼執行較慢

        b)、二是程式碼執行穩定性不高,待操作的元素明明存在,但可能是由於視窗大小發生變化導致元素位置發生變化,甚至元素重疊的情況,導致程式碼報錯“元素不存在”,或者“元素不在所點選的位置(點選操作有可能被另一個元素所接受)”等莫名其妙的錯誤,降低了自動化用例執行的穩定性。

        針對這種情況,對於自動化程式碼中不穩定的部分,經常出錯的部分,可以將這部分對網頁元素進行操作的程式碼換成對應的JavaScript指令碼,由於瀏覽器原生的支援JavaScript,JavaScript程式碼直接在瀏覽器核心中執行,就不會出現元素不在所點選的位置等錯誤,可以大大提高自動化用例執行的穩定性和執行效率。

        下面以使用selenium 呼叫JavaScript指令碼操作百度主頁進行示例演示,首先使用selenium開啟Chrome瀏覽器,載入百度主頁:

#coding:utf-8
"""
    Created by cheng star at 2018/4/15 13:31
    @email : [email protected]
"""

from selenium import webdriver
from time import sleep

url = "http://www.baidu.com"
driver = webdriver.Chrome()
driver.get(url)
driver.implicitly_wait(10)

        百度主頁關鍵字輸入框和查詢按鈕的HTML結構如下:

<span class="bg s_ipt_wr quickdelete-wrap">
    <span class="soutu-btn" style="display: block;"/>
    <input id="kw" class="s_ipt" autocomplete="off" maxlength="255" value="" name="wd"/><!-- 關鍵字輸入框 -->
    <a id="quickdelete" class="quickdelete" href="javascript:;" title="清空" style="top: 0px; right: 0px; display: none;"/>
</span>
<span class="bg s_btn_wr">
    <input id="su" class="bg s_btn btnhover" type="submit" value="百度一下"/><!-- 查詢按鈕 -->
</span>

1、輸入關鍵字並點選查詢按鈕(方法一)

        首先使用DOM物件的getElementById方法定位元素,然後給value屬性賦值實現關鍵字輸入,然後以同樣的方式獲取查詢按鈕物件,並觸發按鈕的click點選操作。

query = """
                var keywordInput = document.getElementById("kw") ;  // 根據全域性唯一的ID獲取輸入框物件
                keywordInput.value = "selenium" ;
                setTimeout(function() {
                    // 延遲 5 秒點選查詢按鈕(setTimeout是非同步執行)
                    var queryBtn = document.getElementById("su") ;  // 根據全域性唯一的ID獲取查詢按鈕物件
                    queryBtn.click() ;
                } , 5000) ;
                """
driver.execute_script(query)

2、輸入關鍵字並點選查詢按鈕(方法二)

        與方法一類似,首先使用DOM物件的getElementById方法定位元素,然後給value屬性賦值實現關鍵字輸入,對於查詢按鈕,也是以同樣的方式獲取查詢按鈕物件,但是並不是呼叫按鈕物件的click方法,而是構造一個event事件物件,並將事件物件繫結在查詢按鈕上實現按鈕的點選操作。這樣做是因為,有些HTML標籤元素沒有onclick屬性,所以直接呼叫click方法並不會觸發物件的點選操作。

# 方法二(對於沒有繫結onclick屬性的元素,click方法無效,可以使用dispatchEvent方法)
query = """
            var keywordInput = document.getElementById("kw") ;  // 根據全域性唯一的ID獲取輸入框物件
            keywordInput.value = "selenium javascript" ;

            setTimeout(function() {
                var queryBtn = document.getElementById("su") ;  // 根據全域性唯一的ID獲取查詢按鈕物件
                var e = document.createEvent("MouseEvents") ;   // 建立事件物件
                e.initEvent("click" , true , true) ;    // 初始化事件物件為 click 事件
                queryBtn.dispatchEvent(e) ;
            } , 5000) ;
            """
driver.execute_script(query)

3、執行JavaScript指令碼返回元素物件 WebElement

        使用python呼叫selenium框架執行JavaScript指令碼也可以將JavaScript的執行結果返回給python的一個物件,物件型別是WebElement,只需要在呼叫的JavaScript指令碼中使用return 語句返回對應的內容即可。

# 執行JS指令碼返回標籤元素物件 WebElement
getKeywordInput = """
                    var keywordInput = document.getElementById("kw") ;
                    return keywordInput ;
                    """
keywordInputElement = driver.execute_script(getKeywordInput)
keywordInputElement.send_keys("selenium javascript")

4、執行JavaScript指令碼在多個相似元素標籤中進行過濾,並操作元素標籤(點選百度主頁的“新聞” 超連結)

        百度主頁“新聞” 超連結對應的HTML結構如下:

<div id="u1">
    <a class="mnav" name="tj_trnews" href="http://news.baidu.com">新聞</a>
    <a class="mnav" name="tj_trhao123" href="http://www.hao123.com">hao123</a>
    <a class="mnav" name="tj_trmap" href="http://map.baidu.com">地圖</a>
    <a class="mnav" name="tj_trvideo" href="http://v.baidu.com">視訊</a>
    <a class="mnav" name="tj_trtieba" href="http://tieba.baidu.com">貼吧</a>
    <a class="mnav" name="tj_trxueshu" href="http://xueshu.baidu.com">學術</a>
    <a class="lb" onclick="return false;" name="tj_login" href="https://passport.baidu.com/v2/?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2F&sms=5">登入</a>
    <a class="pf" name="tj_settingicon" href="http://www.baidu.com/gaoji/preferences.html">設定</a>
    <a class="bri" style="display: block;" name="tj_briicon" href="http://www.baidu.com/more/">更多產品</a>
</div>

        觀察以上HTML內容可以發現,只需要將新聞關鍵字,對所有 a 標籤進行搜尋即可定位新聞超連結,對應的JavaScript程式碼如下:

clickNewsLink = """
                    var linkParentElement = document.getElementById("u1") ;  // 獲取超連結的HTML父元素節點
                    var links = linkParentElement.getElementsByTagName("a") ;   // 獲取linkParentElement元素下的所有超連結
                    for(var i = 0 ; i < links.length ; i ++) {
                        // 通過 新聞 關鍵字過濾需要的超連結
                        var linkText = links[i].innerHTML.trim() ;
                        if(linkText.indexOf("新聞") != -1) {
                            links[i].click() ;  // 點選超連結
                            break ;
                        }
                    }
                    """
driver.execute_script(clickNewsLink)

5、執行JavaScript指令碼下拉瀏覽器滾動條

# 執行JS指令碼操作頁面下拉框
scrollScript = """
                var keywordInput = document.getElementById("kw") ;  // 根據全域性唯一的ID獲取輸入框物件
                keywordInput.value = "selenium" ;
                setTimeout(function() {
                    // 延遲 5 秒點選查詢按鈕(setTimeout是非同步執行)
                    var queryBtn = document.getElementById("su") ;  // 根據全域性唯一的ID獲取查詢按鈕物件
                    queryBtn.click() ;
                    
                    setTimeout(function() {
                        // document.documentElement.scrollTop = 10000 ;    // 適用於除 Chrome瀏覽器外的其他瀏覽器
                        document.body.scrollTop = 10000 ;   // Chrome瀏覽器使用這種方法
                    } , 5000) ; // 延遲5 秒下拉滾動條到頁面最低端
                } , 5000) ;
                """
driver.execute_script(scrollScript)

6、在頁面眾多相似元素中定位需要操作的元素,使用多種條件組合過濾

        當頁面HTML中存在多個相似的元素標籤,很難一次性準確定位時,這時候需要使用一些額外的過濾條件進行判斷,常用的過濾條件包括:hasAttribute判斷元素是否有某一屬性、getAttribute("name") == "XXX"判斷元素屬性內容是否等於XXX、獲取元素標籤內容innerHTML並進行判斷等。

        如下HTML程式碼中包含兩組 a 標籤,兩組 a 標籤對外展示的效果相同,只是當點選第一組連結時會有alert提示框彈出,現在需要使用JavaScript指令碼點選第一組 a 標籤中的“javascript language"連結,並彈出alert提示框,HTML結構如下:

<html>
    <head>
        <title>相似標籤過濾</title>
    </head>
    <body>
        <h2>Part One</h2>
        <div id = "language">
            <a name = "python" href="javascript:alert('part one - python')">python language</a><br>
            <a name = "java" href="javascript:alert('part one - java')">java language</a><br>
            <a name = "C#" href="javascript:alert('part one - C#')">C# language</a><br>
            <a name = "scala" href="javascript:alert('part one - scala')">scala language</a><br>
            <a name = "javascript" href="javascript:alert('part one - javascript')">javascript language</a><br>
        </div>
        
        <h2>Part Two</h2>
        <div id = "language">
            <a href="javascript:alert('part two - python')">python language</a><br>
            <a href="javascript:alert('part two - java')">java language</a><br>
            <a href="javascript:alert('part two - C#')">C# language</a><br>
            <a href="javascript:alert('part two - scala')">scala language</a><br>
            <a href="javascript:alert('part two - javascript')">javascript language</a><br>
        </div>
    </body>
</html>

        對應的JavaScript程式碼如下:

script = """
            var a_tags = document.getElementsByTagName("a") ;   // 獲取當前頁面的所有 a 標籤元素
            for(var i = 0 ; i < a_tags.length ; i ++) {
                // 經過觀察發現,要點選的 javascript 超連結有一個 name = "javascript" 屬性和 關鍵字javascript
                var a_text = a_tags[i].innerHTML.trim() ;   //   獲取超連結的內容
                if(a_tags[i].hasAttribute("name") && a_text.indexOf("javascript language") != -1) {
                    // 獲取具有屬性 name 且內容中包含javascript language 字串的a標籤,並觸發點選操作
                    a_tags[i].click() ;
                    break ;
                }
            }
            """
driver.execute_script(script)
        以上分別介紹了在使用selenium自動化測試框架做自動化指令碼開發時,使用JavaScript指令碼程式碼操作頁面元素的一些常用方法,其中主要用到了DOM(文件物件模型)進行元素查詢定位,並配合使用元素的hasAttribute、getAttribute、innerHTML等屬性方法。

相關推薦

web自動化測試框架selenium呼叫JavaScript程式碼常用操作解析

        在做web專案時,通常需要開發一些自動化用例,自動化用例執行可以設定觸發條件,也可以定時執行,在每次程式碼發生變更的情況下,自動觸發自動化用例執行,可以及時檢測修改程式碼是否引入新的問題,提高產品的自信度。在開發web端自動化用例程式碼時,目前大多采用主流的s

Selenium3 + Python3自動化測試系列十——呼叫JavaScript程式碼

呼叫JavaScript程式碼 一、呼叫JavaScript程式碼方法   Selenium在對瀏覽器操作時會有自動化程式碼中不穩定的部分,經常出錯的部分,可以將這部分對網頁元素進行操作的程式碼換成對應的JavaScript指令碼,由於瀏覽器原生的支援JavaScript,JavaScript程式碼直接在

Java&Selenium Web自動化測試框架理念

一、自動化測試含義 在自動化測試領域內流傳著一個說法:單元測試才是自動化測試的核心,在自動化測試裡,無論框架何等完美都不可能脫離單元測試,單元測試將會是自動化測試裡最小的單位,把它看作單位一,若干個單位一組成了一個整體,它就成了自動化測試; 諸如Python的單元測試框架Unittest、Pytest;J

淺談基於SeleniumWeb自動化測試框架

 ● 面臨的挑戰   從Google到Facebook,從Twitter到新浪微博,新一輪的網際網路熱潮正在全世界蔓延。隨著雲概念的日益清晰,越來越多的企業也已經擺脫了傳統的C/S架構的應用框架而轉投雲端計算的懷抱,Web已經成為我們生活和工作的重心。   有別於傳統

Selenium基於Python的web自動化測試框架(3)-搭建selenium環境

搭建環境 建立selenium虛擬環境 mkvirtualenv selenium-py3 selenium-py3是虛擬環境的名字 由於筆者本地只有python3版本,所以不需要指定python

基於Selenium技術的Web自動化測試框架

時光飛逝,轉瞬之間,已在計算機軟體這個行業,在開發和測試崗位工作了10年。而這其中的酸楚,苦澀和甜美,恐怕只有親身經歷過才能深有體會。 在當今資訊社會,飛速發展的時代大背景下,小小的我,無疑是幸運的。感謝奮戰過的每一個崗位,感謝每一位領導,感謝每一位同事。是他們提供了平臺和

基於Selenium+Python的web自動化測試框架

一、什麼是Selenium? Selenium是一個基於瀏覽器的自動化測試工具,它提供了一種跨平臺、跨瀏覽器的端到端的web自動化解決方案。Selenium主要包括三部分:Selenium IDE、Selenium WebDriver 和Selenium Grid。 Selenium IDE:Firefo

RobotFramework自動化測試框架-Selenium Web自動化(三)關於在RobotFramework中如何使用Selenium很全的總結(下)

本文緊接著RobotFramework自動化測試框架-Selenium Web自動化(二)關於在RobotFramework中如何使用Selenium很全的總結(上)繼續分享RobotFramework中如何使用Selenium進行自動化測試。 本文章節目錄: 1、Get Value 2、Get Webele

web自動化測試python+selenium學習總結----python編輯器pycharm環境安裝

下載安裝檔案 下載最新檔案路徑:https://www.jetbrains.com/pycharm/         安裝:     一直點選下一步即可      破解:     配置hosts檔案。C:\Windows\Sys

2019年 Selenium3與Python3實戰Web自動化測試框架(最新50G)

第1章 課程介紹本章對課程做整體介紹,通過講解web自動化測試需要掌握的知識,到web自動化測試框架的選擇,框架的搭建。1-1 課程介紹 第2章 環境搭建本章講解自動化測試環境的搭建,並通過實際專案實戰講解selenium3的基礎知識,對常用的api進行徹底的分析、設計,再到如何去編寫自動化測試指令碼。2-

自動化測試框架 | selenium+Python,怎樣從0開始搭建一個屬於自己專案的自動化測試框架

這篇博文下面的文章是連結到我知乎專欄的,現啟用新知乎賬號「馬蟻蛋」,對應的專欄「軟體測試精選」,所有文章全部遷移至此賬號了,需要的請關注。此篇文章是,如何從零搭建一個屬於自己專案的自動化測試框架(第一篇

web自動化測試框架搭建( Java+Cucumber+Gradle) _Mac_3

1. 建立一個Gradle projectfile-->new-->Other-->Gradle Project2. 修改build.gradle// plugin  apply pl

web自動化測試框架搭建( Java+Cucumber+Gradle) _Mac_2

一.安裝Gradle1. 使用ruby安裝Mac的包管理器homebrew2. 待brew安裝ok之後,使用brew安裝gradlebrew install gradle3. 確認本機的gradle版本

Web自動化測試框架結構

這是我經過學習和摸索後的成果,自主搭建了一個測試框架結構,目前專案已經完成,所以寫篇部落格來分享一下,也是對自己初期的一個肯定。話不多說,講起。 主要結構: commons:主要用於存放一些公用檔案,如base_page,logger,units等檔案 config:配置項,放HT

Selenium3與Python3實戰Web自動化測試框架

第1章 課程介紹本章對課程做整體介紹,通過講解web自動化測試需要掌握的知識,到web自動化測試框架的選擇,框架的搭建。1-1 課程介紹第2章 環境搭建本章講解自動化測試環境的搭建,並通過實際專案實戰講解selenium3的基礎知識,對常用的api進行徹底的分析、設計,再到如何去編寫自動化測試指令碼。2-1

自動化測試框架selenium+java+TestNG——配置篇

   最近來總結下自動化測試 selenium的一些常用框架測試搭配,由簡入繁,最簡單的就是selenium+java+TestNG了,因為我用的是java,就只是總結下java了。 TestNG線上安裝:  開啟Eclipse   Help ->Install

python之web自動化測試框架

數據源 tool 模塊 efault .html rom dead obj 類型 梳理下搭建web自動化框架的流程: 創建目錄: cases:存放測試用例,unittest框架要求用例名必須以test開頭,所以命名test_case.py test_case.py代碼如下:

Web自動化測試 五 ----- selenium的等待和切換

一、selenium的三種等待 當執行python的selenium程式碼時,如果需要定位一個元素或者點選一個元素,需要考慮到網速等多方面原因,導致頁面載入速度慢,元素還未加載出來,這樣就會導致找不到對應元素,從而報錯的問題,所以要設定等待條件,等待元素加載出來後才執行相應的程式碼。 其中,seleniu

小白學 Python 爬蟲(27):自動化測試框架 Selenium 從入門到放棄(上)

人生苦短,我用 Python 前文傳送門: 小白學 Python 爬蟲(1):開篇 小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝 小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門 小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門 小白學 Pyth

小白學 Python 爬蟲(28):自動化測試框架 Selenium 從入門到放棄(下)

人生苦短,我用 Python 前文傳送門: 小白學 Python 爬蟲(1):開篇 小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝 小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門 小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門 小白學 Pyth