前面介绍了使用TestCafe时如何定位、操作页面元素以及校验执行结果,此次课程将介绍使用TestCafe时如何完成拖动页面元素、模拟鼠标键盘、文件上传下载等操作。在介绍Cypress和Puppeteer时也详细讲解过如何模拟这些操作,故此章节对于这些场景只会简单介绍并给出demo脚本。为了完成此次课程拆分了7个task,接下来将逐个进行简单介绍。
Testcafe框架自身提供了拖动页面元素的api,调用t.dragToElement(fromElementSelector,targetSelector)即可,调用时传入拖动元素的开始位置和结束位置的页面元素selector即可。具体可看下面的案例脚本。同样,执行“npm run test:dragElement”即可运行下面的脚本。
import {Selector} from 'testcafe'
fixture('drag element demo');
test('should drag element successfully', async (t) => {
await t.navigateTo("http://devexpress.github.io/testcafe/example/");
await t.click('#tried-test-cafe');
const toAreaElement = Selector('.slider-container .slider-value').withText('5');
//定位拖动的目标位置元素
await t.dragToElement('.slider-container #slider span', toAreaElement);
//调用testcafe提供的拖动元素api完成拖动操作。
await t.wait(3000);
//此处添加等待命令,方便看到拖动的结果
});
调用t.pressKey(keyname)即可模拟键盘输入操作,下面脚本写了几个常见键值输入,更多可输入的键值可查看官网资料“ Redirecting… ”。对于模拟鼠标操作,框架提供了click、doubleClick、rightClick、hover、dragToElement5个api完成常见的鼠标操作,这几个api使用方式非常简单,前面也分别做过介绍,这里不再重复说明。同样,执行“npm run test:keyBoard”即可运行下面的脚本。
fixture('simulate keyboard action');
test('should simulate keyboard action successfully', async (t) => {
await t.navigateTo('https://devexpress.github.io/testcafe/example/');
await t.typeText('#developer-name','test')
.pressKey('shift+a');
//模拟在输入框中输入大写字母A,这里是通过按住shift+a完成大写字母输入,主要是为了演示模拟键盘键值输入
await t.pressKey('enter');
//模拟输入enter键
await t.pressKey('tab');
//模拟输入tab键
});
TestCafe框架提供了t.switchToIframe(iframeSelector)跳转到iframe上,同时也提供t.switchToMainWindow()跳回主窗口。通过调用这两个方法可以方便定位iframe和非iframe上的页面元素。 具体看下面的demo脚本,同样,执行“npm run test:iframeTest”即可运行下面的测试案例。
import {Selector, t} from 'testcafe'
fixture('control element in iframe demo');
test('should select and click element in iframe successfully', async () => {
await t.navigateTo('https://www.w3schools.com/TAgs/tryit.asp?filename=tryhtml_button_test');
await t.switchToIframe('#iframeResult');
//通过调用switchToIframe切换到iframe上,这样后面的脚本即可定位iframe下的页面元素
await t.expect(Selector('h1').innerText).contains("The button Element");
await t.setNativeDialogHandler(() => true)
.click('button');
await t.switchToMainWindow();
//通过调用switchToMainWindow切换到主窗口上,这样后面的脚本即可定位非iframe下的页面元素
const button= Selector('div button').withText('Run »');
await t.click(button);
});
TestCafe框架没有提供直接的api定位shadow dom下的页面元素,但使用testcafe时可以调用document对象,document对象可以很方便的定位shadow dom下的页面元素。具体看下面的demo脚本,同样,执行“npm run test:shadowDomTest”即可运行下面的测试案例。
import {t,Selector} from 'testcafe'
fixture('shadow dom element demo');
test('should control element in shadow dom successfully', async () => {
await t.navigateTo('https://radogado.github.io/shadow-dom-demo/');
const elementInShadowDom = Selector(()=>document.querySelector('#app').shadowRoot.querySelector('#container p'));
//Selector(()=>document.xxxx)中可以调用document对象,通过document对象定位到shadow dom下的页面元素,然后再操作或者获取页面元素的值
await t.expect(elementInShadowDom.textContent).eql('Dynamically generated content');
//获取页面元素的值并校验是否与期望的值相等
});
TestCafe框架提供了api完成文件上传,且一次还可以上传多个文件。下载文件实际是完成点击操作,和模拟页面点击操作无区别。具体看下面的demo脚本,同样,执行“npm run test:uploadFile”和"npm run test:downloadFile"即可运行下面的测试案例。
//下面是下载文件demo脚本
fixture `Example`
.page `https://js.devexpress.com/Demos/WidgetsGallery/Demo/FileUploader/FileSelection/jQuery/Light/`;
test('Upload Files test', async t => {
await t
.switchToIframe('.demo-frame')
.setFilesToUpload('.dx-fileuploader-input', ['./testFile/test.jpeg'
]);
//调用setFileToUpload(selector,[fileList])即可完成文件上传操作,filelist中可以传入多个文件地址,用逗号隔开。
//需要注意一点,这里的文件路径是相对于测试案例脚本的路径,例如上面脚本中,和测试脚本同一层中存在目录testFile目录,该目录下存在test.jpeg测试文件
});
//下面是下载文件的脚本,下载文件实际模拟的是点击页面元素操作
import {Selector} from 'testcafe'
fixture("download file demo");
test('should download file successfully',async (t)=> {
await t.navigateTo("https://file-examples.com/index.php/sample-documents-download/sample-doc-download/");
const downLoadElement = Selector('td a').withText('Download sample DOC file');
await t.click(downLoadElement);
});
TestCafe提供了api处理弹框。调用" t.setNativeDialogHandler(type,text)=>{} "即可模拟点击弹框中的确认、取消或者关闭按钮。Type指弹框类型,包含alert、confirm、prompt三种类型。 具体使用规则,请看下面的demo代码,同样,执行“npm run test:handleDialog”即可运行下面的脚本。
fixture`handel dialog demo`
.page`http://devexpress.github.io/testcafe/example/`;
test('should handel confirm dialog successfully', async t => {
await t
.setNativeDialogHandler((type, text) => {
switch (type) {
case 'confirm':
switch (text) {
case 'Do you want to subscribe?':
return false;
//返回false,等同于模拟点击confirm类型弹框的取消按钮
case 'Reset information before proceeding?':
return true;
//返回true,等同于模拟点击confirm类型弹框的确认按钮
default:
throw 'Unexpected confirm dialog!';
//假设弹框的message不等于上面两类message,那么抛异常信息,这样运行的案例会失败,并显示定义的异常信息“Unexpected confirm dialog!”
}
case 'prompt':
return 'Hi there';
//如果是prompt类型弹框,模拟输入“Hi there”,然后点击确认按钮
case 'alert':
throw 'An alert was invoked!';
//如果是alert弹框,这里模拟抛出异常。实际场景中,可以根据项目情况模拟处理结果。
}
})
.click('#populate');
//在会出现弹框的方法前面调用.setNativeDialogHandler(),可以根据type类型和text的值确定处理结果
await t.click('#remote-testing');
});
一个应用中,如果某些页面会显示弹框,那么可以把处理弹框的代码封装到page对象中,这样便于测试脚本的复用。这里总结下对于各类弹框返回值的含义。
可以看到,使用testcafe时必须提前能确定出现弹框的位置,例如点击某个按钮时会出现弹框,那么在click操作前调用setNativeDialogHandler方法。如果页面会出现随机弹框,testcafe无法进行处理。puppeteer中通过监听处理弹框,可以处理页面随机弹出的弹框,故如果被测应用中会出现大量随机的弹框,那么建议选择puppeteer测试框架。上面讲解了如何处理不同类型的弹框,接来下看看如何模拟点击浏览器前进和后退按钮。
TestCafe框架没有直接提供api模拟浏览器前进和后退操作,但可以调用window对象实现前进、后退,且可以获取当前页面的地址,校验当前页面是否是期望的页面。具体请看下面的demo脚本,同样,执行“npm run test:pageBackForward”即可运行下面的案例。
import {ClientFunction,t,Selector} from "testcafe";
fixture("page back forward demo");
test("should browser back or forward successfully", async()=> {
const goBack = ClientFunction(() => window.history.back());
//调用window对象,实现浏览器后退操作,这里还使用了用户自定义脚本,这样,在需要后退操作的脚本中调用goBack即可。
const forward = ClientFunction(() => window.history.forward());
//调用window对象,实现浏览器前进操作。
const getLocation = ClientFunction(() => window.location.href);
//获取当前页面的地址
//实际项目中可以把这三个方法封装到util一类的公共脚本中,方便所有测试脚本复用。
await t.navigateTo("https://chercher.tech/practice/popups");
await t.expect(getLocation()).contains('chercher.tech');
await t.hover('#sub-menu');
const googleLink=Selector('div a').withText('Google');
await t.click(googleLink);
await t.expect(getLocation()).contains('google');
await goBack();
await t.expect(getLocation()).contains('chercher.tech');
await forward();
await t.expect(getLocation()).contains('google');
});
TestCafe框架直接提供了hover()方法完成hover操作,使用起来很简单,具体请看下面的脚本,执行“npm run test:hoverTest”即可运行下面的脚本。
import {Selector, t} from 'testcafe'
fixture("hover demo");
test('should hover successfully', async()=> {
await t.navigateTo("https://chercher.tech/practice/popups");
await t.hover('#sub-menu');
//调用hover(selector)完成模拟hover操作
const googleLink=Selector('div a').withText('Google');
await t.click(googleLink)
});