Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Well done!
You have completed Intermediate Selenium WebDriver!
You have completed Intermediate Selenium WebDriver!
Preview
Let's follow best practices and move the code that interacts with our page to a page object class.
In this video, we'll be using this version of the RSVP site.
- It's best practice to use "page objects" with WebDriver. See this video if you're not familiar with them.
- Make
pages
directory.- Make
pages/rsvp.js
file.
- Make
const {Browser, By, Key, until} = require("selenium-webdriver");
const url = "https://treehouse-projects.github.io/selenium-webdriver-intermediate/waits/app/index.html";
// Define a class to represent the page.
// Instances of this class will be responsible for controlling WebDriver to do operations on the page.
class RsvpPage {
// The class constructor sets up new instances of the class.
// We're going to have the test pass in a browser driver object when creating a page object.
// The page object will call methods on the driver object to control the page.
constructor(driver) {
// We'll set the "driver" property of the new object to equal the driver that's passed in.
this.driver = driver;
// The locators property will be an object containing locators for the different page
// elements we need to find.
this.locators = {
// Our first test uses this locator to find the list that we'll populate with invitees.
// We'll move the locator from the test to here.
invitedList: By.id('invitedList'),
// Our second tests uses this locator to find the form to register invitees.
// We'll move that here, too.
registrationForm: By.id('registrar'),
}
}
// This method will load the page. It will use whatever driver object we pass into the constructor.
open() {
this.driver.get(url);
}
}
// We need to set the values that will be returned when this module is required from another module.
// We'll set it up to return the RsvpPage class.
module.exports = RsvpPage;
- Then we need to update our test to load our new module and use the class.
const {Browser, By, Key, until} = require("selenium-webdriver");
const {suite} = require("selenium-webdriver/testing");
const assert = require('assert');
// Load the RsvpPage class.
const RsvpPage = require('../pages/rsvp.js')
suite(function(env) {
describe('RSVP site', async function() {
let driver;
// Define a variable to hold the page object here so that it stays in scope
// for all our tests as well.
let page;
before(async function() {
driver = await env.builder().build();
// Create a new page object that will use our driver object.
// Store it in the page variable.
page = new RsvpPage(driver);
// Instead of calling driver.get() ourselves, we'll let the page object
// load the page for us.
await page.open();
});
it('has invitee list', async function() {
// Use the locator from the page object instead.
let elements = await driver.findElements(page.locators.invitedList);
assert(elements.length > 0);
});
it('has registration form', async function() {
// Use the locator from the page object instead.
let elements = await driver.findElements(page.locators.registrationForm);
assert(elements.length > 0);
});
after(async function() {
driver.quit();
});
});
});
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
We've made a lot of improvements
to our test code, but
0:00
there's one more change we need to make
to bring it in line with best practices.
0:02
In Selenium, it's generally best to wrap
up interactions with the actual page in
0:06
a page object class.
0:11
If you're not familiar with Selenium
page object, see the teacher's notes.
0:12
Let's create a new directory
that'll hold our page object code.
0:17
So within our project directory,
0:20
I'm gonna create a new subdirectory
to hold all our page object code.
0:22
I'll name it Pages,
within the Pages subdirectory,
0:26
I'll create a new file to
hold our RSVP page object.
0:30
And I'll name it rsvp.js.
0:36
First up we're going to need to import
some of the code from Selenium web driver
0:40
into this file as well.
0:43
So I'm gonna copy this over
from the actual test code.
0:44
And part of the whole point for creating
a page object class is to ensure that our
0:52
test itself doesn't have to know
the details of how to connect to the page.
0:56
So I'm going to move this URL for
the page out of our test and
0:59
over to the page object class file.
1:04
Now I need to define a class
to represent the page.
1:08
Instances of this class
will be responsible for
1:10
controlling web driver to
do operations on the page.
1:13
So, I'll say class RsvpPage,
1:16
we need to set the values that we will be
returned when this module is required from
1:23
another module.
1:27
We'll set it up to return
the RsvpPage class.
1:28
So I'll say module.exports=RsvpPage.
1:31
The class constructor sets up
new instances of the class.
1:39
We're going to have the test pass in
a browser driver object when creating
1:43
a page object.
1:47
The page object will call methods on
the driver object to control the page.
1:48
We'll set the driver property of the new
object to equal the driver that's
1:53
passed in.
1:56
The locators property will be
an object containing locators for
2:01
the different page
elements we need to find.
2:04
Our first test uses a locator to find
the list that will populate with invitees.
2:09
We'll move the locator
from the test to here.
2:14
So I'll set the invitedList
attribute of the locators object
2:17
to equal By.id, and we'll look for
an ID of invitedList.
2:22
Our second test uses a locator to
find the form to register invitees,
2:30
we'll move that here, too.
2:34
We'll set up a property
named registationForm.
2:36
And we'll use the By.id locator
with an ID of registrar.
2:41
We're also going to want
a method to load the page.
2:49
It'll use whatever driver object
we pass into the constructor.
2:52
So we'll name our method open.
2:55
And within the open method,
3:00
we'll use the driver object that
belongs to this page object.
3:02
And we'll call the get method on it to
get the URL constant that we set above.
3:08
Let's save that, and now we need to update
our test to load our new module and
3:14
use the class.
3:18
So up here, I'll load the RsvpPage
class from our new module.
3:20
The double dot here means to
go to the parent directory,
3:32
the parent of the test directory.
3:35
And then go to the pages subdirectory,
and load the rsvp.js module.
3:38
Next, just as we did for our driver
variable, we need to define the variable
3:45
up here to hold the page object, so
that it stays in scope for all our tests.
3:49
So, we'll say let's page,
3:53
we won't actually assign anything to the
page variable until our before function.
3:56
Where we'll say that
the page = new RsvpPage
4:01
object and we'll pass the driver to
the constructor for that object.
4:07
And instead of calling
driver.get ourselves,
4:14
we'll let the page object
load the page for us.
4:16
So we'll say page.open Now remember,
we're trying to move all knowledge
4:18
of how to interact with the page, from our
test itself into the page object class.
4:24
So we're gonna take this snippet
of code here, that looks for
4:29
an element with an id of invitedList.
4:33
And instead,
4:36
we're going to use the locator that we
set up here in our page object class.
4:37
So we'll say page.locaters.invitedList.
4:41
We'll do the same down here
instead of looking an element up
4:49
with an id of registrar.
4:52
We'll just say that we're going
to use the locater that is
4:54
defined in our page object class,
which is registrationForm.
4:59
Let's make sure that our test is saved and
make sure that our page objects is
5:06
saved as well, and go back to our
terminal, and try running mocha again.
5:12
And our test will run
the same as they ever have.
5:19
The difference is that the tails
of how they interact with the page
5:21
have been moved to the page object class.
5:24
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up