我想在Protractor中实现的是获取页面上的所有链接并逐个查看它们以检查是否有链接路由到404页面。
以下代码来自我的电子邮件页面对象,请注意我在href上调用replace
,因为我要测试的页面上的链接格式如下:https://app.perflectie.nl/something
和我想在https://staging.perflectie.nl
和我的localhost上进行端到端测试。
// Used to check for 'broken' links - links that lead to a 404 page
Email.prototype.verifyLinkQuality = function() {
browser.driver.findElements(by.css('a')).then(function (elements) {
elements.forEach(function(el) {
// Change the url to the base url this tests now runs on, e.g. localhost or staging
el.getAttribute('href').then(function(href) {
var url = href.replace(/https\:\/\/app\.perflectie\.nl\//g, localhost);
browser.get(url);
browser.driver.getCurrentUrl().then(function(url) {
expect(url).not.toContain('/Error/');
browser.navigate().back();
});
});
});
});
}
如果我运行此命令,则会收到以下错误消息:
Failed: Element not found in the cache - perhaps the page has changed since it was looked up
For documentation on this error, please visit: http://seleniumhq.org/exceptions/stale_element_reference.html
Build info: version: '2.48.2', revision: '41bccdd', time: '2015-10-09 19:59:12'
System info: host: 'DESKTOP-QLFLPK5', ip: '169.254.82.243', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_73'
Driver info: driver.version: unknown
我不知道为什么失败了,我非常感谢你的帮助。
答案 0 :(得分:2)
我会使用map()
将所有链接收集到一个数组中,而不是往返(通常导致陈旧的元素引用错误导致DOM更改/重新加载)逐个处理它们。这也会对测试的性能产生积极的影响:
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.analytics.Analytics;
import com.google.api.services.analytics.AnalyticsScopes;
import com.google.api.services.analytics.model.Accounts;
import com.google.api.services.analytics.model.GaData;
import com.google.api.services.analytics.model.Profiles;
import com.google.api.services.analytics.model.Webproperties;
import java.io.File;
import java.io.IOException;
/**
* A simple example of how to access the Google Analytics API using a service
* account.
*/
public class HelloAnalytics {
private static final String APPLICATION_NAME = "Hello Analytics";
private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();
private static final String KEY_FILE_LOCATION = "/path/to/your.p12";
private static final String SERVICE_ACCOUNT_EMAIL = "<SERVICE_ACCOUNT_EMAIL>@developer.gserviceaccount.com";
public static void main(String[] args) {
try {
Analytics analytics = initializeAnalytics();
String profile = getFirstProfileId(analytics);
System.out.println("First Profile Id: "+ profile);
printResults(getResults(analytics, profile));
} catch (Exception e) {
e.printStackTrace();
}
}
private static Analytics initializeAnalytics() throws Exception {
// Initializes an authorized analytics service object.
// Construct a GoogleCredential object with the service account email
// and p12 file downloaded from the developer console.
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountPrivateKeyFromP12File(new File(KEY_FILE_LOCATION))
.setServiceAccountScopes(AnalyticsScopes.all())
.build();
// Construct the Analytics service object.
return new Analytics.Builder(httpTransport, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME).build();
}
private static String getFirstProfileId(Analytics analytics) throws IOException {
// Get the first view (profile) ID for the authorized user.
String profileId = null;
// Query for the list of all accounts associated with the service account.
Accounts accounts = analytics.management().accounts().list().execute();
if (accounts.getItems().isEmpty()) {
System.err.println("No accounts found");
} else {
String firstAccountId = accounts.getItems().get(0).getId();
// Query for the list of properties associated with the first account.
Webproperties properties = analytics.management().webproperties()
.list(firstAccountId).execute();
if (properties.getItems().isEmpty()) {
System.err.println("No Webproperties found");
} else {
String firstWebpropertyId = properties.getItems().get(0).getId();
// Query for the list views (profiles) associated with the property.
Profiles profiles = analytics.management().profiles()
.list(firstAccountId, firstWebpropertyId).execute();
if (profiles.getItems().isEmpty()) {
System.err.println("No views (profiles) found");
} else {
// Return the first (view) profile associated with the property.
profileId = profiles.getItems().get(0).getId();
}
}
}
return profileId;
}
private static GaData getResults(Analytics analytics, String profileId) throws IOException {
// Query the Core Reporting API for the number of sessions
// in the past seven days.
return analytics.data().ga()
.get("ga:" + profileId, "7daysAgo", "today", "ga:sessions")
.execute();
}
private static void printResults(GaData results) {
// Parse the response from the Core Reporting API for
// the profile name and number of sessions.
if (results != null && !results.getRows().isEmpty()) {
System.out.println("View (Profile) Name: "
+ results.getProfileInfo().getProfileName());
System.out.println("Total Sessions: " + results.getRows().get(0).get(0));
} else {
System.out.println("No results found");
}
}
}
请注意,也无需明确解析$$('a').map(function(link) {
return link.getAttribute("href").then(function (href) {
return href.replace(/https\:\/\/app\.perflectie\.nl\//g, localhost);
});
}).then(function(links) {
links.forEach(function(link) {
browser.get(link);
expect(browser.getCurrentUrl()).not.toContain('/Error/');
});
});
,因为.getCurrentUrl()
会在达到预期之前为我们隐式执行此操作。