python变相调用htmlunit

发布时间:2019-09-22 07:44:41编辑:auto阅读(1664)

    目前团队使用的自动化测试框架是robotframework+webdriver(IE)+python,据说是从趋势那边搬过来的j_0057.gif。webdriver里面,IEdriver是运行最慢的,因此每次跑一遍用例都要花上4个小时j_0064.gif,这个如果在工作日跑的话,半天工作时间就没了,如果在下班后跑,发现问题又不能及时调试,很烦……

    Java里的webdriver有个好东西是htmlunit,这个在python版的webdriver里却没有,应该跟htmlunit纯用java写的有关。htmlunit跑用例可以不打开浏览器在后台跑,因此在webdriver里面是最快的。python里面虽然没有htmlnuit,但是有个第三方库是Jpype,可以通过模拟java虚拟机直接调用jar包!因此我的想法是用java写个接口把htmlunit常用方法再封装下,然后用python通过jpype来调用接口。

    package htunit;
    import java.util.concurrent.TimeUnit;
    import org.openqa.selenium.By;
    import org.openqa.selenium.JavascriptExecutor;
    import org.openqa.selenium.Keys;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.htmlunit.HtmlUnitDriver;
    import org.openqa.selenium.ie.InternetExplorerDriver;
    import org.openqa.selenium.remote.DesiredCapabilities;
    import com.thoughtworks.selenium.DefaultSelenium;
    public class htunit {
        WebDriver driver;  
        public htunit(){
            DesiredCapabilities htmlunitcapabilities=DesiredCapabilities.htmlUnit();
            htmlunitcapabilities.setJavascriptEnabled(true);
            htmlunitcapabilities.setCapability(HtmlUnitDriver.INVALIDSELECTIONERROR, false);
            htmlunitcapabilities.setCapability(HtmlUnitDriver.INVALIDXPATHERROR, false);
            //driver=new InternetExplorerDriver();
            driver=new HtmlUnitDriver(htmlunitcapabilities);
            driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
            driver.manage().timeouts().setScriptTimeout(5, TimeUnit.SECONDS);
            driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
            //driver.setJavascriptEnabled(true);
        }
        public void deletecookie() throws Exception{
            driver.manage().deleteAllCookies();
        }
        public String getpage(){
            return driver.getPageSource();
        }
        public String gettitle(){
            return driver.getTitle();
        }
        public void get(String url){
            driver.get(url);
        }
        public void SetInputTextById(String Id,String value) throws Exception{
            driver.findElement(By.id(Id)).clear();
            driver.findElement(By.id(Id)).sendKeys(value);
        }
        public void SetInputTextByName(String name,String value) throws Exception{
            driver.findElement(By.name(name)).clear();
            driver.findElement(By.name(name)).sendKeys(value);
        }
        public void SetInputTextByXpathWithoutClear(String xpath,String value) throws Exception{
            driver.findElement(By.xpath(xpath)).sendKeys(value);
        }
        public void SetInputTextByXpath(String xpath,String value) throws Exception{
            driver.findElement(By.xpath(xpath)).clear();
            driver.findElement(By.xpath(xpath)).sendKeys(value);
        }
        public void ClickButtonByXpath(String CSS) throws Exception{
                driver.findElement(By.xpath(CSS)).click();
            //sleep short time in python
        }
        public void ClickById(String Id) throws Exception{
            driver.findElement(By.id(Id)).click();
        }
        public void ClickByName(String name) throws Exception{
            driver.findElement(By.name(name)).click();
        }
        public void ClickByXpath(String xpath) throws Exception{
            driver.findElement(By.xpath(xpath)).click();
        }
        public void DoubleClickByXpath(String xpath) throws Exception{
            driver.findElement(By.xpath(xpath)).click();
        }
        public void SelectFrame(String frame) throws Exception{
            driver.switchTo().frame(frame);
            //driver.switchTo().window(frame);
            //return frame;
        }
        public void ClickMsgBox() throws Exception{
            driver.switchTo().activeElement().sendKeys(Keys.RETURN);
        }
        //problem
        public void SelectComboxById(String Id,int dts) throws Exception{
            ClickById(Id);
            WebElement a=driver.switchTo().activeElement();
            while (dts!=0){
                a.sendKeys(Keys.DOWN);
                dts--;
            }
            a.sendKeys(Keys.RETURN);
        }
        public void SwitchToActiveFrame() throws Exception{
            driver.switchTo().defaultContent();
        }
        public void SelectComboxByXpath(String xpath,int dts) throws Exception{
            ClickByXpath(xpath);
            WebElement a=driver.switchTo().activeElement();
            while (dts!=0){
                a.sendKeys(Keys.DOWN);
                dts--;
            }
            a.sendKeys(Keys.RETURN);
        }
        public void UIIsElementPresent(String locator) throws Exception{
            int a=103;
        }
        public void UIVerifyTextByXpath(String xpath,String val) throws Exception{
                                                                                                                                                                                                                                                                               
        }
        public String UIGetTextByXpath(String xpath) throws Exception{
            return driver.findElement(By.xpath(xpath)).getText();
        }
        public boolean UIVerifyTextByJsId(String Id,String val) throws Exception{
            JavascriptExecutor js=(JavascriptExecutor)driver;
            String tx=js.executeScript("return document.getElementById('"+ Id+ "').value").toString();
            //question
            boolean re=tx.contains(val);
            return re;
        }
        public boolean UIVerifyValueByJsIdIsPositive(String Id) throws Exception{
            JavascriptExecutor js=(JavascriptExecutor)driver;
            String tx=js.executeScript("return document.getElementById('"+ Id+ "').value").toString();
            if (Integer.parseInt(tx)>0)
                return true;
            else
                return false;
        }
        public void SelectDateByName(String name, String sdate) throws Exception{
                                                                                                                                                                                                                                                                               
        }
        public void SelectDateById(String Id, String sdate) throws Exception{
                                                                                                                                                                                                                                                                               
        }
        public void SelectDate(String element,String sdate) throws Exception{
                                                                                                                                                                                                                                                                               
        }
        public void AddContactInfo(String Id,String phone,String address) throws Exception{
            ClickById(Id);
            driver.switchTo().activeElement();
            ClickById("btnAdd.ContactInfoWin");
            SetInputTextById("phoneNo.ContactInfoModifyWin", phone);
            SetInputTextById("custAddr.ContactInfoModifyWin", address);
            ClickById("btnSave.ContactInfoModifyWin");
            ClickById("btnSave.ContactInfoWin");
            ClickMsgBox();
        }
        public void AddEventInfo(String Xpath,String btnId, String Id1,int Id2,int Id3,String name1,String name2) throws Exception{
            ClickByXpath(Xpath);
            ClickById(btnId);
            SetInputTextById("eventTitle.EventDetail", Id1);
            SelectComboxById("alertType.EventDetail", Id2);
            SelectDateByName("alertStrDate", name1);
            SetInputTextByName("alertStrTime", name2);
            driver.switchTo().activeElement().sendKeys(Keys.RETURN);
            SelectComboxById("fowardTime.EventDetail", Id3);
            ClickById("save.EventDetail");
            ClickMsgBox();
        }
        public int switch_to_active_element(int cmd) throws Exception{
            if(cmd==1){
            driver.switchTo().activeElement().sendKeys(Keys.DOWN);
            return 1;}
            else if(cmd==2){
            driver.switchTo().activeElement().sendKeys(Keys.RIGHT);
            //driver.switchTo().activeElement().sendKeys(Keys.RETURN);
                                                                                                                                                                                                                                                                               
            return 2;}
            else if(cmd==3){
            driver.switchTo().activeElement().sendKeys(Keys.RETURN);
            return 3;}
            return 4;
        }
        public void switch_to_default_content() throws Exception{
            driver.switchTo().defaultContent();
            //driver.switchTo().
        }
        public void waitfor(String xpath) throws Exception{
                                                                                                                                                                                                                                                                               
        }
        public String getsource() throws Exception{
            return driver.getPageSource();
        }
    }

    由于后来其他原因失败了,导致这边只封装了最基本的接口。这里拿网易邮箱来做测试,python代码:

    #coding=utf8
    import jpype
    import time
    import os.path
    start=time.time()
    jarpath=os.path.join(os.path.abspath('.'),'E:/lib')
    print jarpath
    jvmPath=jpype.getDefaultJVMPath()
    jpype.startJVM(jvmPath,"-Djava.ext.dirs=%s"%jarpath)
    jpype.java.lang.System.out.println("hello world!")
    javaclass=jpype.JClass("htunit.htunit")
    temp=javaclass()
    temp.deletecookie()
    url='http://mail.163.com'
    username='****'
    pwd='****'
    id='loginBtn'
    temp.get(url)
    temp.SetInputTextById("idInput", username)
    temp.SetInputTextById("pwdInput", pwd)
    temp.ClickById(id)
    print time.time()-start

    上面java代码中如果24行不注释,注释25行则会调用IE接口。下面是在我机器上跑的时间对比:

    171245420.png

    172639195.png

    结果是htmlunit壮烈牺牲了,java报了一个跟证书有关的错,这个应该跟网易邮箱有安全认证有关……因此只能在按提交前把时间打印出来了下,大概是IEdriver的三分之一,如果有应用的地方,确实很快啊!

    我是把java所有htmlunit的jar包都拖到E:\lib下面,并且把导出的jar包也放到E:\lib下面,要不然jpype会找不到的。另外这种情况下使用htmlunit的时候浏览器不要设代理,否则也会报错,当然htmlunit本身是可以设代理的,我没研究j_0010.gif

    最后之所以不在项目中应用主要是因为团队项目对js依赖很大,而这个是htmlunit最大的软肋………

关键字