Jasmine - 通过 Webdriver 测试链接 I/O
Jasmine - Testing links via Webdriver I/O
我一直在使用来自 Jasmine 的 Webdriver I/O 进行 end-to-end 测试。一个特定的场景给了我很大的挑战。
我有一个页面有 5 links。 link 的数量实际上是一个挑战,因为页面是动态的。我想测试 links 以查看每个 links' title
是否与它 links 到的页面的 title
相匹配。由于 link 是动态生成的,我不能只对每个 link 进行硬编码测试。所以,我正在尝试以下操作:
it('should match link titles to page titles', function(done) {
client = webdriverio.remote(settings.capabilities).init()
.url('http://www.example.com')
.elements('a').then(function(links) {
var mappings = [];
// For every link store the link title and corresponding page title
var results = [];
for (var i=0; i<links.value.length; i++) {
mappings.push({ linkTitle: links.value[0].title, pageTitle: '' });
results.push(client.click(links.value[i])
.getTitle().then(function(title, i) {
mappings[i].pageTitle = title;
});
);
}
// Once all promises have resolved, compared each link title to each corresponding page title
Promise.all(results).then(function() {
for (var i=0; i<mappings.length; i++) {
var mapping = mappings[i];
expect(mapping.linkTitle).toBe(mapping.pageTitle);
}
done();
});
});
;
});
我什至无法确认我是否正确获得了 link 称号。我相信有些事情我完全误解了。我什至没有得到每个 links title
属性。我肯定没有得到相应的页面标题。我想我在这里迷失了封闭世界。但是,我不确定。
更新 - 11 月 24 日
我还是没弄明白。但是,我认为这与 Webdriver I/O uses Q promise 库这一事实有关。我得出这个结论是因为以下测试有效:
it('should match link titles to page titles', function(done) {
var promise = new Promise(function(resolve, reject) {
setTimeout(function() { resolve(); }, 1000);
});
promise.then(function() {
var promises = [];
for (var i=0; i<3; i++) {
promises.push(
new Promise(function(resolve, reject) {
setTimeout(function() {
resolve();
}, 500);
})
);
}
Promise.all(promises).then(function() {
expect(true).toBe(true)
done();
});
});
但是,以下 无效 工作:
it('should match link titles to page titles', function(done) {
client = webdriverio.remote(settings.capabilities).init()
.url('http://www.example.com')
.elements('a').then(function(links) {
var mappings = [];
// For every link store the link title and corresponding page title
var results = [];
for (var i=0; i<links.value.length; i++) {
mappings.push({ linkTitle: links.value[0].title, pageTitle: '' });
results.push(client.click(links.value[i])
.getTitle().then(function(title, i) {
mappings[i].pageTitle = title;
});
);
}
// Once all promises have resolved, compared each link title to each corresponding page title
Q.all(results).then(function() {
for (var i=0; i<mappings.length; i++) {
var mapping = mappings[i];
expect(mapping.linkTitle).toBe(mapping.pageTitle);
}
done();
});
})
;
});
我没有收到任何例外情况。然而,Q.all
中的代码似乎并没有被执行。我不确定在这里做什么。
阅读 WebdriverIO 手册,我觉得您的方法有一些错误:
elements('a')
returns WebElement JSON 个对象(https://code.google.com/p/selenium/wiki/JsonWireProtocol#WebElement_JSON_Object) NOT WebElements, so there is no title
property thus linkTitle
will always be undefined
- http://webdriver.io/api/protocol/elements.html
- 此外,因为它是一个 WebElement JSON 对象,所以您不能将其用作
client.click(..)
输入,它需要一个选择器字符串而不是一个对象 - http://webdriver.io/api/action/click.html。单击 WebElement JSON 对象 client.elementIdClick(ID)
而不是采用 WebElement JSON 对象的 ELEMENT
属性 值。
- 当执行
client.elementIdClick
时,client
将导航到页面,尝试在下一个 ID 的 for 循环周期中调用 client.elementIdClick
将失败,因为有没有这样的元素,因为你离开了页面。听起来像 invalid element cache....
.
因此,我为您的任务提出另一个解决方案:
- 像使用
elements('a')
一样查找所有元素
- 对每个元素使用
client.elementIdAttribute(ID)
读取 href
和 title
并存储在对象中
- 遍历所有对象,使用
client.url('href')
导航到每个 href
-s,使用 .getTitle
获取页面的 title
并进行比较object.title
.
我试验的来源,不是 Jasmine 的 运行,但应该给出一个想法:
var client = webdriverio
.remote(options)
.init();
client
.url('https://www.google.com')
.elements('a')
.then(function (elements) {
var promises = [];
for (var i = 0; i < elements.value.length; i++) {
var elementId = elements.value[i].ELEMENT;
promises.push(
client
.elementIdAttribute(elementId, 'href')
.then(function (attributeRes) {
return client
.elementIdAttribute(elementId, 'title')
.then(function (titleRes) {
return {href: attributeRes.value, title: titleRes.value};
});
})
);
}
return Q
.all(promises)
.then(function (results) {
console.log(arguments);
var promises = [];
results.forEach(function (result) {
promises.push(
client
.url(result.href)
.getTitle()
.then(function (title) {
console.log('Title of ', result.href, 'is', title, 'but expected', result.title);
})
);
});
return Q.all(promises);
});
})
.then(function () {
client.end();
});
注意:
- 当链接使用 JavaScript 事件处理程序而不是
href
属性触发导航时,这无法解决您的问题。
我一直在使用来自 Jasmine 的 Webdriver I/O 进行 end-to-end 测试。一个特定的场景给了我很大的挑战。
我有一个页面有 5 links。 link 的数量实际上是一个挑战,因为页面是动态的。我想测试 links 以查看每个 links' title
是否与它 links 到的页面的 title
相匹配。由于 link 是动态生成的,我不能只对每个 link 进行硬编码测试。所以,我正在尝试以下操作:
it('should match link titles to page titles', function(done) {
client = webdriverio.remote(settings.capabilities).init()
.url('http://www.example.com')
.elements('a').then(function(links) {
var mappings = [];
// For every link store the link title and corresponding page title
var results = [];
for (var i=0; i<links.value.length; i++) {
mappings.push({ linkTitle: links.value[0].title, pageTitle: '' });
results.push(client.click(links.value[i])
.getTitle().then(function(title, i) {
mappings[i].pageTitle = title;
});
);
}
// Once all promises have resolved, compared each link title to each corresponding page title
Promise.all(results).then(function() {
for (var i=0; i<mappings.length; i++) {
var mapping = mappings[i];
expect(mapping.linkTitle).toBe(mapping.pageTitle);
}
done();
});
});
;
});
我什至无法确认我是否正确获得了 link 称号。我相信有些事情我完全误解了。我什至没有得到每个 links title
属性。我肯定没有得到相应的页面标题。我想我在这里迷失了封闭世界。但是,我不确定。
更新 - 11 月 24 日 我还是没弄明白。但是,我认为这与 Webdriver I/O uses Q promise 库这一事实有关。我得出这个结论是因为以下测试有效:
it('should match link titles to page titles', function(done) {
var promise = new Promise(function(resolve, reject) {
setTimeout(function() { resolve(); }, 1000);
});
promise.then(function() {
var promises = [];
for (var i=0; i<3; i++) {
promises.push(
new Promise(function(resolve, reject) {
setTimeout(function() {
resolve();
}, 500);
})
);
}
Promise.all(promises).then(function() {
expect(true).toBe(true)
done();
});
});
但是,以下 无效 工作:
it('should match link titles to page titles', function(done) {
client = webdriverio.remote(settings.capabilities).init()
.url('http://www.example.com')
.elements('a').then(function(links) {
var mappings = [];
// For every link store the link title and corresponding page title
var results = [];
for (var i=0; i<links.value.length; i++) {
mappings.push({ linkTitle: links.value[0].title, pageTitle: '' });
results.push(client.click(links.value[i])
.getTitle().then(function(title, i) {
mappings[i].pageTitle = title;
});
);
}
// Once all promises have resolved, compared each link title to each corresponding page title
Q.all(results).then(function() {
for (var i=0; i<mappings.length; i++) {
var mapping = mappings[i];
expect(mapping.linkTitle).toBe(mapping.pageTitle);
}
done();
});
})
;
});
我没有收到任何例外情况。然而,Q.all
中的代码似乎并没有被执行。我不确定在这里做什么。
阅读 WebdriverIO 手册,我觉得您的方法有一些错误:
elements('a')
returns WebElement JSON 个对象(https://code.google.com/p/selenium/wiki/JsonWireProtocol#WebElement_JSON_Object) NOT WebElements, so there is notitle
property thuslinkTitle
will always beundefined
- http://webdriver.io/api/protocol/elements.html- 此外,因为它是一个 WebElement JSON 对象,所以您不能将其用作
client.click(..)
输入,它需要一个选择器字符串而不是一个对象 - http://webdriver.io/api/action/click.html。单击 WebElement JSON 对象client.elementIdClick(ID)
而不是采用 WebElement JSON 对象的ELEMENT
属性 值。 - 当执行
client.elementIdClick
时,client
将导航到页面,尝试在下一个 ID 的 for 循环周期中调用client.elementIdClick
将失败,因为有没有这样的元素,因为你离开了页面。听起来像invalid element cache....
.
因此,我为您的任务提出另一个解决方案:
- 像使用
elements('a')
一样查找所有元素
- 对每个元素使用
client.elementIdAttribute(ID)
读取href
和title
并存储在对象中 - 遍历所有对象,使用
client.url('href')
导航到每个href
-s,使用.getTitle
获取页面的title
并进行比较object.title
.
我试验的来源,不是 Jasmine 的 运行,但应该给出一个想法:
var client = webdriverio
.remote(options)
.init();
client
.url('https://www.google.com')
.elements('a')
.then(function (elements) {
var promises = [];
for (var i = 0; i < elements.value.length; i++) {
var elementId = elements.value[i].ELEMENT;
promises.push(
client
.elementIdAttribute(elementId, 'href')
.then(function (attributeRes) {
return client
.elementIdAttribute(elementId, 'title')
.then(function (titleRes) {
return {href: attributeRes.value, title: titleRes.value};
});
})
);
}
return Q
.all(promises)
.then(function (results) {
console.log(arguments);
var promises = [];
results.forEach(function (result) {
promises.push(
client
.url(result.href)
.getTitle()
.then(function (title) {
console.log('Title of ', result.href, 'is', title, 'but expected', result.title);
})
);
});
return Q.all(promises);
});
})
.then(function () {
client.end();
});
注意:
- 当链接使用 JavaScript 事件处理程序而不是
href
属性触发导航时,这无法解决您的问题。