What's the best way to write assertions that should apply across every page in a site?
I'm testing to see if an element exists in the footer of my site, so the element should exist on all pages.
I am thinking of writing a separate file for testing template elements of the site, and then include this in all specs. It doesn't seem like anyone else is doing this though?
First of all, for writing cleaner tests and having a better understanding of what your target site consists of, apply the Page Object pattern and split the parts of your web pages into different page objects. For instance, footer
, header
can and should be separate page objects that would be reused across different web pages of your site.
More on the topic:
- Using Page Objects to Organize Tests
- Protractor Page Objects (Tutorial, very detailed)
- PageObject (Martin Fowler)
- Using Page Objects to Overcome Protractor's Shortcomings
As far as I understand the question, to follow the "DRY" principle you want to have some sort of the "shared" jasmine specs that you can define once and run in multiple test suites.
This is exactly what DRYing up Jasmine Specs with Shared Behavior article is describing. The idea is rather simple - define a function with your test suites inside and call it from other test suites. Example:
create a function which accepts a context - page object - and contains the footer specific reusable tests:
function testFooter(footer) {
describe("(shared)", function () {
describe("should show footer with necessary information", function () {
it("should show copyright", function () {
expect(footer.copyright.getText()).toEqual('Copyright 2014');
});
});
});
}
call the function from other test suites passing the context - footer page object:
var FooterPage = require('./footer.po.js');
describe('Contacts page', function () {
var scope = {};
beforeEach(function () {
browser.get('/contacts/');
browser.waitForAngular();
scope.page = new ContactsPage();
});
// other contacts page specific suites
// ...
testFooter(new FooterPage());
});
You may need to adjust and improve the code to make it work, but the idea stays the same: define once and reuse. Passing around page objects just makes it a lot cleaner and transparent.
Also see:
- What's a good way to reuse test code using Jasmine?
- Protractor Page Objects Inheritance
I am using specs in a way that a spec speaks about some scenario, not always about particular page, so it's not "one spec, one page". I would consider that testing the same thing across many specs as bad practice if the conditions in specs can't influence the presence of your element.
In general I don't think it's even necessary to test things like that. I would rather consider if it's even possible for your element not to be present or, if there are some conditions which influence that, and test those situations.
If you insist on testing this (e.g. there are static pages which don't share content and your element is added by hand and you have to be sure), I would create single spec for testing the presence of this element and in there, define a list of pages to test. So the test would cover the testing of that element's presence on all the listed pages.