Selenium 请问 selenium 这种写法有实现思路吗?

退之 · 2018年01月18日 · 最后由 樂易 回复于 2018年01月24日 · 4136 次阅读

driver.page("登陆页面").sendKeys("用户名输入框", "Admin").sendKeys("密码输入框", "1234567").click("登录按钮");

如题。

共收到 17 条回复 时间 点赞

有点不太明白楼主的思路,你是想把几个步骤用一条句子写下来吗?但是你有没有考虑过这几个步骤之间的间隔是时间呢?比如网络延迟造成的控件载入迟缓问题?

退之 #16 · 2018年01月18日 Author

是的,连续的输入,增加可读性。
driver.page("登陆页面").sendKeys("用户名输入框", "Admin",3).sendKeys("密码输入框", "1234567",3).click("登录按钮",3);

这样呢,增加一个变量代表间隔时间

driver.page("登陆页面").sendKeys("用户名输入框", "Admin").sendKeys("密码输入框", "1234567").click("登录按钮");

driver.page("登陆页面")
driver.sendKeys("用户名输入框", "Admin")
driver.sendKeys("密码输入框", "1234567")
driver.click("登录按钮");

上面两种写法的可读性你觉得上面一种更好吗?楼主果然思考方式独辟蹊径

退之 #14 · 2018年01月19日 Author
simple 回复

上面一种写法是连续性的,想在这个页面的哪些元素执行哪些操作;下面一种写法是断点性的,一步一个操作,那么多的 driver 看起来有点冗余

楼主可以试下 Scala

你可以封装类 Aciton ,在类中 封装 page(),sendKeys() 方法,每个方法 return self,这样就可以实现链式的调用了。

伪代码 (Python 3 )


class Aciton:
    def page(self):
        do something
        return self

    def send_keys(self):
        do something
        return self

    def click(self):
        do something
        return self




if __name__ == __main__:
    ac = Aciton()
    ac.page().send_keys().click()

链式结构,每个方法都 return self 就好了

学习了,还有 return self 这种方法,但是看上去越来越抽象了呢😅

没觉得这种连续操作能增加可读性,就像中文为什么需要有标点符号而不提倡一句话说完所有的事情一样。另外操作过程中可能需要做其他事情,我个人不是很喜欢这种写法,楼主莫怪哈

退之 回复

那你看下面这样的脚本呢?可以自己封装一套 bot-style api
你那样写跟 js 里面 Promise 的 then() 一样,如果你选择用 puppeteer 去做自动化就可以,webdriver 这样做有点傻

Webdriver by Java

@Test
public void baiduSearchExam() {
    String searchText = "砖家叫兽";

    startWebDriver();
    this.setMaxWaitTime(5);

    get("http://www.baidu.com/");
    sendKeys(By.id("kw"), searchText);
    click(By.id("su"));
    click(By.linkText(searchText + "_百度图片"));
    ASSERT.assertTrue(elementExists(By.linkText(searchText + "_百度图片"), 2));

    closeWebDriver();
}

puppeteer by js

const puppeteer = require("puppeteer");
puppeteer.launch({
        executablePath: './chromium/chrome.exe',
        headless: true,
        timeout: 10000
    }).then(async browser => {        
    const page = await browser.newPage();
    var searchStr = "砖家叫兽";

    page.setViewport({
        width: 1280,
        height: 1024,
    });

    await page.goto("https://cn.bing.com/", { waitUntil: "networkidle2" });

    await page.type("#sb_form_q", searchStr, {delay: 100}); 
    page.click('#sb_form_go');
    await page.waitForNavigation();
    //await page.waitForSelector('.b_mopb');

    await page.screenshot({ path: "./test/results/bing.png" });
    browser.close();
});
0x7C00 回复

嗯 这种方式能实现

退之 #11 · 2018年01月19日 Author
simple 回复

每个人有自己喜欢的方式

槽神 回复

没用过 puppeteer,有机会去试试

推荐 PageObject 模式 + 静态引用 试一下。

你可以写个装饰类,对 WebDriver 再次封装下

step 转链式调用? 为啥不进一步,直接变成 keywords bind?

同意上面的说法,用 pageObject 模式,定位元素可以放在单独的一个配置中,这样每次元素位置变更,都可以改配置直接读取;实现方法最好写在框架里面,脚本是直接调用的

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册