selenium--driver.switchTo()

在自動化測試中,會遇到多窗口、多iframe、多alert的狀況。此時,會使用driver.switchTo()來解決。javascript

下面時關於driver.switchTo()的詳細介紹:css

1.多windows操做。html

在頁面A上操做時,點擊某個元素以後,可能會打開新的窗口。若是須要操做新窗口上的元素,進必須跳轉到新的窗口上。java

    @Test
    public void fTest() throws InterruptedException {
        //launchBrowser是本身封裝的方法 ,主要是爲了啓動瀏覽器驅動,打開指定url,頁面加載的等待超時時間設置爲3S
     //這裏測試使用的是qq郵箱的登陸頁面
launchBrowser("https://mail.qq.com/cgi-bin/loginpage", 3); //定位並點擊「手機版」元素,打開手機版頁面,此時會打開新的窗口 driver.findElement(By.partialLinkText("手機版")).click(); Thread.sleep(3000); //獲取當前窗口句柄(此時是得到https://mail.qq.com/cgi-bin/loginpage頁面的句柄) String currentHandle = driver.getWindowHandle(); //得到全部的窗口句柄,若是不是currentHandle,則進入 Set<String> windowHandles = driver.getWindowHandles(); for (String windowHandle : windowHandles) { if (!currentHandle.equals(windowHandle) ) { //進入到手機版頁面的窗口 driver.switchTo().window(windowHandle); } } //此時才能操做手機版頁面的元素 driver.findElement(By.cssSelector("a[href='http://app.mail.qq.com/cgi-bin/appdownload?check=false&stype=1&subtype=8&fr=&url=ios&downloadclick=']")).click();;

      //若是想要操做qq郵箱登陸頁面的元素,此時須要退回到以前的窗口
      driver.switchTo().window(currentHandle);mysql

         
    }

上面是經過switchTo()方法,進入新的頁面,並操做對應元素。jquery

還有另爲一種方式:linux

<a href="http://app.mail.qq.com/" target="_blank">手機版</a>ios

咱們點擊連接以後,打開新的窗口,就是由於這個連接中有屬性 target="_blank"web

因此,咱們能夠經過JQuery腳原本去除該元素的target的屬性。去除以後再點擊的時候,就不會打開新的瀏覽器窗口了。sql

這個qq郵箱的頁面http://app.mail.qq.com/,首次執行JQuery會失敗,第二次會成功。猜想多是由於第一次執行以後,會觸發引入jQuery的操做。爲了使代碼具備通用性,直接引入jQuery。

可是不少安全性高一些的網站,會限制引入的域名地址。會形成引入JQuery失敗。爲了解決該問題,教你們一個萬能的方法:下載某頁面的JQuery源代碼,放到本地文件中。封裝讀取並執行JQuery的幫助類。

幫助類代碼:

package com.claire.jing.utils;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;

import org.openqa.selenium.JavascriptExecutor;

public class ImportJQueryUtil {
    
    public static void importJQueryUtil(JavascriptExecutor jse) {
        StringBuffer buffer = new StringBuffer();
        
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream("F:\\開發資料\\jQuery源碼\\jquery-1.10.2.min.js");
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        InputStreamReader reader = new InputStreamReader(inputStream);
        BufferedReader bufferedReader = new BufferedReader(reader);
        String temp=null;
        try {
            while ((temp = bufferedReader.readLine()) !=null) {
                buffer.append(temp);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        
        jse.executeScript(buffer.toString());
    }
    
    

}

使用JQuery來刪除元素指定屬性

@Test
    public void fTest() throws InterruptedException {
        //方式2:使用JQuery來刪除target="_blank"
        //launchBrowser是本身封裝的方法 ,主要是爲了啓動瀏覽器驅動,打開指定url,頁面加載的等待超時時間設置爲3S
        launchBrowser("https://mail.qq.com/cgi-bin/loginpage", 20);
        
        //該js腳本判斷是否引入了JQuery
        String js = "return (typeof($)==\"undefined\")";
        boolean flag = (boolean)((JavascriptExecutor)driver).executeScript(js);
        
        //若是沒引入,則調用幫助類,執行JQuery源碼。
        //這裏之因此不使用直接增長Script節點引入JQuery,是由於不少安全性高一些的網站,會限制引入的域名地址。會形成引入JQuery失敗
        if (flag) {
            ImportJQueryUtil.importJQueryUtil((JavascriptExecutor)driver);            
        }
        //這裏能夠判斷下,是否引入成功了
        //System.out.println((boolean)((JavascriptExecutor)driver).executeScript(js));
        

        
        
        //<a href="http://app.mail.qq.com/" target="_blank">手機版</a>
        //該a連接帶有屬性target="_blank"--擁有該屬性的連接,點擊後纔會打開新的頁面。只要經過js來移除該屬性,點擊以後,就不會打開新的瀏覽器窗口了
        String jquery = "var com=$('a[href=\"http://app.mail.qq.com/\"]');"
                + "com.removeAttr(\"target\");"
                + "com[0].click();";
        
        ((JavascriptExecutor)driver).executeScript(jquery);
        //觀察一下執行結果
        Thread.sleep(4000);
        quit();
        

    }

2.Iframe

有些頁面元素時包在IFrame中的,此時想要操做Iframe上的元素,必須先進入Iframe裏面去。

 下面舉例多層iframe嵌套的狀況:

    @Test
    public void fTest() throws InterruptedException {
        launchBrowser("http://XXX/index.html", 10);
        //爲了避免須要每次都登陸,能夠設置添加cookie()
                driver.manage().deleteCookieNamed("JSESSIONID");
                driver.manage().addCookie(new Cookie("qqq", "BD04BA5FA2019D6C9DB28E25A5B14D85"));
                try {
                    //爲了cookie使用的久一些,能夠設置cookie的有效期。
                    //即便這裏設置了cookie有效期,cookie也是有可能會無效的(通常狀況下,會將sessionId存到cookie中):
                    //第一:服務端的session是有有效期的,若是session過時了,那麼這個cookie也就無效了。
                    //第二,當服務端的內存報警時,就可能會清除session。這種狀況下,你的cookie也會失效
                    //第三,當服務端重啓以後,緩存和session都會清空的,你的cookie天然就失效了
                    driver.manage().addCookie(new Cookie("JSESSIONID", "FB9F06DDF0D15C491EFAD6D444893F80","/lmcanon_web_auto",(new SimpleDateFormat("yyyy-MM-dd hh:m:ss")).parse("2018-12-12 12:12:12") ));
                } catch (ParseException e) {
                    logger.error("日期轉換出錯");
                    e.printStackTrace();
                }
        
        driver.get("http://XXX/index.html");
        logger.info("成功打開首頁");
        
        
        driver.findElement(By.cssSelector("i[class=\"Hui-iconfont menu_dropdown-arrow\"]")).click();
        logger.info("成功定位習題管理,並點擊");
        
        
        //定位習題管理子標籤,該標籤是須要點擊父標籤習題管理以後,纔會可見的。
        //下面使用了ExpectedConditions中提供的visibilityOfElementLocated()來判斷該字標籤是否可見,可見以後纔對其進行點擊操做
        WebDriverWait wait = new WebDriverWait(driver, 3);            
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("a[data-href=\"stem-list.html\"]"))).click();
        logger.info("成功定位子元素習題管理並點擊");
        
        //想要點擊「添加習題」按鈕,發現該按鈕在iframe中,必須先進入iframe才能定位並操做該元素
        WebElement IframeElement = waitElement(By.cssSelector("iframe[src='stem-list.html']"));
        driver.switchTo().frame(IframeElement);
        logger.info("成功進入第一層Iframe,並進入");
        
        driver.findElement(By.cssSelector("a[class=\"btn btn-primary radius\"]")).click();
        logger.info("成功定位第一層frame內的添加習題按鈕並點擊");
        
        //嵌套iframe狀況,想要點擊添加習題彈窗上的元素,就必須進入第二層iframe
        //進入第二層Iframe
        //首先定位第二層iframe <iframe scrolling="auto" allowtransparency="true" id="layui-layer-iframe2" name="layui-layer-iframe2" onload="this.className='';" class="" frameborder="0" src="./stemAndItem-add.html" style="height: 467px;"></iframe>
        WebElement iframe2 = driver.findElement(By.id("layui-layer-iframe2"));
        driver.switchTo().frame(iframe2);
        logger.info("成功進入第二層iframe");
        
        //定位第二層iframe的元素
        //<select class="select valid" name="subjectType" aria-required="true" aria-invalid="false"><option value="0">--請選擇--</option><option value="1">軟件測試基礎</option><option value="2">mysql數據庫</option><option value="3">linux</option><option value="4">java</option></select>
        WebElement subjectType = driver.findElement(By.cssSelector("select[name=\"subjectType\"]"));
        Select select = new Select(subjectType);
        select.selectByIndex(2);
        logger.info("成功定位第二層iframe內的題目領域元素,並選擇爲mysql數據庫");
        
        
        //退出當前iframe-----注意:下面方法是退回到的top window 層
        driver.switchTo().defaultContent();
        logger.info("成功退回到first frame.");
        
        //操做topWindow上的元素,證實成功退回
        driver.findElement(By.cssSelector("i[class=\"Hui-iconfont menu_dropdown-arrow\"]")).click();
        logger.info("成功定位習題管理,並點擊");
        
        
    }

 

3.alert操做

其實如今前臺系統中的alert頁面愈來愈少了。由於它的體驗不是很好。可是在一些後臺系統中,仍是會遇到alert操做。Alert彈窗分三種,Alert,prompt(須要輸入內容的彈窗),confirm


1. alert() 彈出個提示框 (肯定) 
警告消息框 alert 方法有一個參數,即但願對用戶顯示的文本字符串。該字符串不是 HTML 格式。該消息框提供了一個「肯定」按鈕讓用戶關閉該消息框,而且該消息框是模式對話框,也就是說,用戶必須先關閉該消息框而後才能繼續進行操做。

 

2. confirm() 彈出個確認框 (肯定,取消) 
確認消息框 使用確認消息框可向用戶問一個「是-或-否」問題,而且用戶能夠選擇單擊「肯定」按鈕或者單擊「取消」按鈕。confirm 方法的返回值爲 true 或 false。該消息框也是模式對話框:用戶必須在響應該對話框(單擊一個按鈕)將其關閉後,才能進行下一步操做。

 

3. prompt() 彈出個輸入框(肯定,取消)。

若是用戶單擊提示框的取消按鈕,則返回 null。若是用戶單擊確認按鈕,則返回輸入字段當前顯示的文本。

在用戶點擊肯定按鈕或取消按鈕把對話框關閉以前,它將阻止用戶對瀏覽器的全部輸入。在調用 prompt() 時,將暫停對 JavaScript 代碼的執行,在用戶做出響應以前,不會執行下一條語。

 

    @Test
    public void fTest() throws InterruptedException {
    
        launchBrowser("D:\\javascript\\Untitled-3.html", 10);
        
        WebDriverWait wait = new WebDriverWait(driver, 3);
        Alert alert2 = wait.until(ExpectedConditions.alertIsPresent());
        System.out.println(alert2.getText());
        //取消
        alert2.dismiss();
        //肯定
        alert2.accept();
        //輸入內容
        alert2.sendKeys("hello");
        Thread.sleep(4000);        
        
    }
本站公眾號
   歡迎關注本站公眾號,獲取更多信息