大家好,欢迎来好好学习,天天向上。本节课的主要内容是多浏览器的操作,一个测试脚本打开多个浏览器,炫不炫酷,刺不刺激
在这之前,先说一个浏览器的兼容性测试,我们之前的测试中一直在用chrome浏览器,但是自动化测试不能只用一个单一的浏览器走到底,偶尔也可能用一用火狐或者IE,下面用IE浏览器举个栗子


如果下载的时候网速不给力或者其他原因cnpm install不管用也不要慌,可以去网上下载一个驱动,selenium官网上点击链接就能下载对应的驱动

下载完成后放入自己喜欢的路径下面,然后配置一下环境变量,不会配?没事,我教你






多浏览器的操作,这里大家注意一下,为了方便演示所以多浏览器的例子还都是chrome的操作,上面的ie暂时先忘掉,别被误导,还拿我们的老搭档,老猴子和小猴子来说吧:有一天小猴子在我们Cnode社区上发了个帖子说“山下的桃树上桃子熟了,再不摘就都被隔壁老王抢走了”,老猴子看到了回帖说“你站在此处不要走动,我先去摘两个橘子回来”
这个场景让我们用自动化脚本来实现的话就是这样的:
1.小猴子先打开一个浏览器,登录网站
2.老猴子再打开一个浏览器,登录网站
3.小猴子发帖
4.老猴子回帖

async function Userlogin(username, passwd) {
await driver.get('http://118.31.19.120:3000/signin');
await driver.findElement({ id: 'name' }).sendKeys(username)
await driver.findElement({ id: 'pass' }).sendKeys(passwd)
await driver.findElement({ id: 'pass' }).submit();
}
接下来,你一定会把老猴子和小猴子的登录操作写进来,已经定义过登陆的方法Userlogin了,直接调用就行了
Given(/^用户小猴子登录系统$/, async function () {
await Userlogin('testuser2', '123456')
});
Then(/^用户老猴子也登录系统$/, async function () {
await Userlogin('testuser3', '123456')
});
没有错,小猴子用的testuser2登录,老猴子用testuser3,但是这个时候你去运行一下,好像哪里不太对嘛,两个用户用的同一个浏览器登录的,我们不是说好的两只猴子各用一个吗,有bug,得改!

exports.otherdriver = createDriver();
webdriver.js里面添加的别搞错了啊,然后去hook.js文件里,这里也要改的,耐心一点,最开始定义常量的部分加一个otherdriver
const { driver, otherdriver} = require('./web_driver');
最后再回到我们写脚本的地方,有两个driver了,代码里当然要改了
async function Userlogin(driver, username, passwd) {
await driver.get('http://118.31.19.120:3000/signin');
await driver.findElement({ id: 'name' }).sendKeys(username)
await driver.findElement({ id: 'pass' }).sendKeys(passwd)
await driver.findElement({ id: 'pass' }).submit();
}
Given(/^用户小猴子登录系统$/, async function () {
await Userlogin(driver, 'testuser2', '123456')
});
Then(/^用户老猴子也登录系统$/, async function () {
await Userlogin(otherdriver, 'testuser3', '123456')
});
在参数前面把各自的driver加上了,没有太大改动,这时候运行试试

真的是两个浏览器没骗你哈,接下来的操作,那就是常规操作了,记得两个用户各自用自己的driver,代码怎么写的,还是那句话,之前的课里,蹲墙角补课去!
发帖和回帖的过程中,大家有没有发现,在编辑文字的时候,元素定位以及操作都是一样一样的,那么这里面,我们把编辑文字的部分,再用一个统一的方法提炼出来,叫它edit_context,小猴子发帖和老猴子回帖的时候都会调用这个方法,sendkeys里面传对应的参数,这里面我们给参数命名为content
async function edit_context(driver,content){
await driver.findElement({css:'.CodeMirror-scroll'}).click();
let input_area = await driver.findElement({css:'.CodeMirror-cursor.CodeMirror-secondarycursor'})
await driver.actions().mouseMove(input_area).sendKeys(content).perform();
await driver.findElement({css:'.span-primary.submit_btn'}).click();
}
接下来是小猴子和老猴子的发布和回复部分
发布话题,用post_topic方法,最后就是调用了上面那个编辑话题的function看出来了吧
async function post_topic(driver,title,content){
await driver.get('http://118.31.19.120:3000/topic/create');
await driver.findElement({id:'tab-value'}).click();
await driver.findElement({css:'#tab-value > option:nth-child(2)'}).click();
await driver.findElement({id:'title'}).sendKeys(title);
await edit_context(driver,content)
}
回复话题,用reply_topic方法,同样是在最后调用编辑话题的方法,这里面有一个刷新页面的操作,为什么这么做呢,因为我们在一开始的时候分别做了小猴子和老猴子登录的操作,小猴子发布话题后,老猴子刷新一下页面就可以立马看到小猴子刚刚发布的话题,进行回复了
async function reply_topic(driver,content){
await driver.navigate().refresh();
await driver.findElement({css:'#topic_list > div:nth-child(1) > div > a'}).click();
await edit_context(driver,content)
}
最后小猴子和老猴子的动作,引号部分就是给上面方法里传的对应参数,title和contect
When(/^用户小猴子发布一个话题$/, async function () {
await post_topic(driver, '山下的桃树上桃子熟了','山下的桃树上桃子熟了,再不摘就都被隔壁老王抢走了');
});
Then(/^用户老猴子回复用户小猴子的话题$/, async function () {
await reply_topic(otherdriver, '你站在此处不要走动,我先去摘两个橘子回来')
});
附上完整代码
const { Given, When, Then } = require('cucumber');
const assert = require('assert');
const { driver, otherdriver } = require('../support/web_driver');
async function Userlogin(driver, username, passwd) {
await driver.get('http://118.31.19.120:3000/signin');
await driver.findElement({ id: 'name' }).sendKeys(username)
await driver.findElement({ id: 'pass' }).sendKeys(passwd)
await driver.findElement({ id: 'pass' }).submit();
}
async function edit_context(driver,content){
await driver.findElement({css:'.CodeMirror-scroll'}).click();
let input_area = await driver.findElement({css:'.CodeMirror-cursor.CodeMirror-secondarycursor'})
await driver.actions().mouseMove(input_area).sendKeys(content).perform();
await driver.findElement({css:'.span-primary.submit_btn'}).click();
}
async function post_topic(driver,title,content){
await driver.get('http://118.31.19.120:3000/topic/create');
await driver.findElement({id:'tab-value'}).click();
await driver.findElement({css:'#tab-value > option:nth-child(2)'}).click();
await driver.findElement({id:'title'}).sendKeys(title);
await edit_context(driver,content)
}
async function reply_topic(driver,content){
await driver.navigate().refresh();
await driver.findElement({css:'#topic_list > div:nth-child(1) > div > a'}).click();
await edit_context(driver,content)
}
Given(/^用户小猴子登录系统$/, async function () {
await Userlogin(driver, 'testuser2', '123456')
});
Then(/^用户老猴子也登录系统$/, async function () {
await Userlogin(otherdriver, 'testuser3', '123456')
});
When(/^用户小猴子发布一个话题$/, async function () {
await post_topic(driver, '山下的桃树上桃子熟了','山下的桃树上桃子熟了,再不摘就都被隔壁老王抢走了');
});
Then(/^用户老猴子回复用户小猴子的话题$/, async function () {
await reply_topic(otherdriver, '你站在此处不要走动,我先去摘两个橘子回来')
});
运行出的结果就是

更多精彩内容,欢迎关注腾讯课堂
https://ke.qq.com/course/281565#tuin=173f40be,周一至周五晚上8:00
有问题欢迎加入QQ讨论群:707467292(node.js自动化测试)
测试工具CukeTest下载地址http://www.cuketest.com/
网友评论