Bummer! This is just a preview. You need to be signed in with a Basic account to view the entire video.
Start a free Basic trial
to watch this video
Selenium supports complex mouse interactions, such as drag and drop.
In this video, we'll be using this page.
- Selenium supports complex mouse interactions, such as drag and drop.
- Here we have a page set up by
crossbrowsertesting.com
to demonstrate using JavaScript to support a drag-and-drop interaction.- You can click and hold your mouse button on the left-hand element, and drag it all over the page.
- If you drop it over the target element, its text will change to "Dropped!".
- Let's write a test that ensures this drag-and-drop interaction continues to work correctly.
- As we did in the previous video, we'll start with the test code, then move to the page object code.
test/drag_and_drop.js
// This code is just like we saw in the previous video: we load all the usual
// modules, as well as our page object class.
// The before function sets up a driver and page object for us, and loads
// the page, and the after function quits the driver.
const {Browser, By, Key, until} = require("selenium-webdriver");
const {suite} = require("selenium-webdriver/testing");
const assert = require('assert');
const DragAndDropPage = require('../pages/drag_and_drop.js');
suite(function(env) {
describe('Drag and drop demo', function() {
let driver;
let page;
before(async function() {
driver = await env.builder().build();
page = new DragAndDropPage(driver);
await page.open();
});
// We want to write a test that confirms that dragging draggable element
// updates the droppable element's status text.
it('Updates status text', async function() {
// We'll set up a method on the page object that performs the
// drag and drop for us. Here we call that method, and wait for it
// to complete.
await page.dragDrop();
// Now we need to find the droppable element. We'll use a locator
// that we'll define in the page object.
let droppable = await driver.findElement(page.locators.droppable);
// We wait for the text of the droppable element to be retrieved,
// and store the result.
var text = await droppable.getText();
// And finally, we assert that text includes the word "Dropped".
assert(text.includes("Dropped"));
});
after(async function() {
driver.quit();
});
});
});
Now, let's fill in the page object that will perform these operations.
pages/drag_and_drop.js
// We've loaded all the usual webdriver objects, pasted in our page's URL, and
// set up a page object class and constructor.
const {Browser, By, Key, until} = require("selenium-webdriver");
const url = 'https://crossbrowsertesting.github.io/drag-and-drop.html'
class DragAndDropPage {
constructor(driver) {
this.driver = driver;
this.locators = {
// If we right-click on the draggable element and choose Inspect,
// we can see it has an ID of "draggable". We'll set that up as
// a locator here.
draggable: By.id('draggable'),
// The droppable element has an ID of "droppable". We'll set up
// a locator for that as well.
droppable: By.id('droppable'),
}
}
open() {
this.driver.get(url);
}
// Here's the method that will perform the drag-and-drop. It needs to
// be asynchronous, of course.
async dragDrop() {
// First we find the draggable element, using the locator we defined
// above. Then we find the droppable element.
let draggable = await this.driver.findElement(this.locators.draggable);
let droppable = await this.driver.findElement(this.locators.droppable);
// To perform the drag-and-drop action, we need to take the driver
// object, and call the actions() method on it to retrieve an object
// that lets us perform page actions. To get the action we're going to
// perform, we call the dragAndDrop() method on the actions object,
// and pass it the element we're dragging and the element we're dropping
// onto. Finally, we call perform() on the returned action object.
// These methods return promises, of course, so we need to use the
// await keyword to wait for them to resolve.
await this.driver
.actions()
.dragAndDrop(draggable, droppable)
.perform();
}
}
module.exports = DragAndDropPage;
- On Firefox, this code will probably work as is. On Chrome and with other browsers, you may encounter an error.
- This can be fixed by running the actions in "bridge mode".
- Insert
{bridge:true}
as an argument to the call to theactions()
method. - With that in place, if we re-run our test, it should work.
- You can learn more about the issue here.
Other actions
You can see a list of other available actions in the Selenium WebDriver API documentation
-
0:00
Selenium supports complex mouse interactions such as drag and drop.
-
0:04
Here we have a page set up by CrossBrowserTesting.com to demonstrate
-
0:09
using JavaScript to support a drag and drop interaction.
-
0:12
You can click and hold your mouse button on the left-hand element and
-
0:15
drag it all over the page.
-
0:17
If you drop it over the target element, its text will change to Dropped.
-
0:22
Let's write a test that ensures this drag and
-
0:24
drop interaction continues to work correctly.
-
0:27
As we did in the previous video,
-
0:29
we'll start with the test code, then move to the page object code.
-
0:33
This test code is just like we saw in the previous video.
-
0:36
We load all the usual modules as well as our page object class.
-
0:40
The before function sets up a driver and page object for us.
-
0:44
And the after function quits the driver.
-
0:47
We want to write a test that confirms that dragging a draggable element
-
0:51
updates the droppable element's status text.
-
0:55
So we'll start our test out here, saying that it should update the status text.
-
1:03
We'll set up a method on the page object that performs the drag and drop for us.
-
1:08
Here we call that method and wait for it to complete.
-
1:11
Now, we need to find the droppable element.
-
1:13
We'll use a locator that we'll define in the page object.
-
1:22
We wait for the text of the droppable element to be retrieved and
-
1:26
store the result.
-
1:29
And finally, we assert that the text includes the word Dropped.
-
1:36
Let's save that.
-
1:39
And now let's fill in the page object that will perform these operations.
-
1:43
We've loaded all the usual WebDriver objects, pasted in our page's URL, and
-
1:48
set up a page object class and constructor.
-
1:52
Now we need to be able to locate the draggable element.
-
1:55
Let me reload the page here.
-
1:56
And let's right-click on our draggable element and choose Inspect.
-
2:02
We can see that it has an id of draggable.
-
2:06
So let's set that up as a locator here on our page object.
-
2:13
Likewise, the droppable element has an id of droppable.
-
2:18
So we'll use a By.id locator to find that as well.
-
2:27
Now we need to define the method that will perform the drag and drop.
-
2:30
It needs to be asynchronous of course.
-
2:35
First, we find the draggable element using the locator we defined above.
-
2:47
Then we find the droppable element using its locator.
-
2:59
To perform the drag and drop action, we're going to need to access the driver object.
-
3:03
We'll do this using await, since it's going to return a promise.
-
3:12
We need to call the actions method on the driver to
-
3:15
retrieve an object that lets us perform page actions.
-
3:19
We'll have more info on actions in the teacher's notes.
-
3:23
To get the action we're going to perform,
-
3:27
we call the dragAndDrop method on the actions object and
-
3:31
we pass at the element we're dragging, draggable, and
-
3:36
the element we're dropping onto, droppable.
-
3:40
Finally, we need to call the perform method on the returned action object.
-
3:46
Whoops, it looks like I made a little syntax error here,
-
3:49
an extra set of parentheses.
-
3:51
Let me fix that real quick and then let's save this and go to our terminal and
-
3:54
let's try running it.
-
3:57
With the Firefox driver, this code will probably work as is.
-
4:01
On Chrome and with other browsers,
-
4:03
you may encounter this error, Unrecognized command: actions.
-
4:07
This can be fixed by running the actions in bridge mode.
-
4:10
You'll need to insert bridge:true as an argument to
-
4:13
the call to the actions method.
-
4:16
Let's save that.
-
4:17
And with that in place, let's try re-running our test.
-
4:22
This time it works.
-
4:24
See the teacher's notes if you'd like more info about this workaround.
-
4:29
Let's go back to the test and I'm going to comment out
-
4:32
the portion that quits the driver so that you can see it in action.
-
4:37
We run it again.
-
4:40
And you can see that the test ran and
-
4:42
it dragged the draggable element on top of the droppable element.
You need to sign up for Treehouse in order to download course files.
Sign up