diff --git a/lib/api/web-element/commands/isActive.js b/lib/api/web-element/commands/isActive.js
new file mode 100644
index 000000000..abac2f471
--- /dev/null
+++ b/lib/api/web-element/commands/isActive.js
@@ -0,0 +1,30 @@
+/**
+ * Determines if an element is currently active/focused in the DOM.
+ *
+ * For more info on working with DOM elements in Nightwatch, refer to the Finding & interacting with DOM Elements guide page.
+ *
+ * @example
+ * describe('isActive Demo', function() {
+ * it('test isActive', function(browser) {
+ * browser.element('#search')
+ * .isActive()
+ * .assert.equals(true);
+ * });
+ *
+ * it('test async isActive', async function(browser) {
+ * const result = await browser.element('#search').isActive();
+ * browser.assert.equal(result, true);
+ * });
+ * });
+ *
+ * @since 3.9.0
+ * @method isActive
+ * @memberof ScopedWebElement
+ * @instance
+ * @syntax browser.element.find(selector).isActive()
+ * @link /#get-active-element
+ * @returns {ScopedValue}
+ */
+module.exports.command = function () {
+ return this.runQueuedCommandScoped('isElementActive');
+};
diff --git a/lib/transport/selenium-webdriver/method-mappings.js b/lib/transport/selenium-webdriver/method-mappings.js
index cde1de0ef..709e85d47 100644
--- a/lib/transport/selenium-webdriver/method-mappings.js
+++ b/lib/transport/selenium-webdriver/method-mappings.js
@@ -493,6 +493,15 @@ module.exports = class MethodMappings {
};
},
+ async isElementActive(webElementOrId) {
+ const element = this.getWebElement(webElementOrId);
+ const elementId = await element.getId();
+
+ const currentActiveElementId = await this.methods.session.getActiveElement.call(this);
+
+ return elementId === currentActiveElementId;
+ },
+
async setElementProperty(webElementOrId, name, value) {
const element = this.getWebElement(webElementOrId);
diff --git a/test/src/api/commands/web-element/testIsActive.js b/test/src/api/commands/web-element/testIsActive.js
new file mode 100644
index 000000000..b0ba235a1
--- /dev/null
+++ b/test/src/api/commands/web-element/testIsActive.js
@@ -0,0 +1,130 @@
+const assert = require('assert');
+const {WebElement} = require('selenium-webdriver');
+const MockServer = require('../../../../lib/mockserver.js');
+const CommandGlobals = require('../../../../lib/globals/commands-w3c.js');
+const common = require('../../../../common.js');
+const Element = common.require('element/index.js');
+
+describe('element().isActive() command', function() {
+ before(function (done) {
+ CommandGlobals.beforeEach.call(this, done);
+ });
+
+ after(function (done) {
+ CommandGlobals.afterEach.call(this, done);
+ });
+
+ it('test .element().isActive() active', async function() {
+ MockServer.addMock({
+ url: '/session/13521-10219-202/element/active',
+ method: 'GET',
+ response: JSON.stringify({
+ value: {
+ 'element-6066-11e4-a52e-4f735466cecf': '0'
+ }
+ })
+ }, true);
+
+ const resultPromise = this.client.api.element('#signupSection').isActive();
+ assert.strictEqual(resultPromise instanceof Element, false);
+ assert.strictEqual(typeof resultPromise.find, 'undefined');
+
+ assert.strictEqual(resultPromise instanceof Promise, false);
+ assert.strictEqual(typeof resultPromise.then, 'function');
+
+ const result = await resultPromise;
+ assert.strictEqual(result instanceof WebElement, false);
+ assert.strictEqual(result, true);
+ });
+
+ it('test .element().isActive() not active', async function() {
+ MockServer.addMock({
+ url: '/session/13521-10219-202/element/active',
+ method: 'GET',
+ response: JSON.stringify({
+ value: {
+ 'element-6066-11e4-a52e-4f735466cecf': 'random-elem'
+ }
+ })
+ }, true);
+
+ const resultPromise = this.client.api.element('#signupSection').isActive();
+ assert.strictEqual(resultPromise instanceof Element, false);
+ assert.strictEqual(typeof resultPromise.find, 'undefined');
+
+ assert.strictEqual(resultPromise instanceof Promise, false);
+ assert.strictEqual(typeof resultPromise.then, 'function');
+
+ const result = await resultPromise;
+ assert.strictEqual(result instanceof WebElement, false);
+ assert.strictEqual(result, false);
+ });
+
+ it('test .element().find().isActive()', async function() {
+ MockServer.addMock({
+ url: '/session/13521-10219-202/element/active',
+ method: 'GET',
+ response: JSON.stringify({
+ value: {
+ 'element-6066-11e4-a52e-4f735466cecf': '1'
+ }
+ })
+ }, true);
+
+ const resultPromise = this.client.api.element('#signupSection').find('#helpBtn').isActive();
+ assert.strictEqual(resultPromise instanceof Element, false);
+ assert.strictEqual(typeof resultPromise.find, 'undefined');
+
+ assert.strictEqual(resultPromise instanceof Promise, false);
+ assert.strictEqual(typeof resultPromise.then, 'function');
+
+ const result = await resultPromise;
+ assert.strictEqual(result instanceof WebElement, false);
+ assert.strictEqual(result, true);
+ });
+
+ it('test .element.find().isActive() not active', async function() {
+ MockServer.addMock({
+ url: '/session/13521-10219-202/element/active',
+ method: 'GET',
+ response: JSON.stringify({
+ value: {
+ 'element-6066-11e4-a52e-4f735466cecf': 'random-elem'
+ }
+ })
+ }, true);
+
+ const resultPromise = this.client.api.element.find('#signupSection').isActive();
+ assert.strictEqual(resultPromise instanceof Element, false);
+ assert.strictEqual(typeof resultPromise.find, 'undefined');
+
+ assert.strictEqual(resultPromise instanceof Promise, false);
+ assert.strictEqual(typeof resultPromise.then, 'function');
+
+ const result = await resultPromise;
+ assert.strictEqual(result instanceof WebElement, false);
+ assert.strictEqual(result, false);
+ });
+
+ it('test .element().isActive() assert', async function() {
+ MockServer.addMock({
+ url: '/session/13521-10219-202/element/active',
+ method: 'GET',
+ response: JSON.stringify({
+ value: {
+ 'element-6066-11e4-a52e-4f735466cecf': '0'
+ }
+ })
+ }, true);
+
+ const resultPromise = this.client.api.element('#signupSection').isActive();
+ assert.strictEqual(resultPromise instanceof Element, false);
+ assert.strictEqual(typeof resultPromise.find, 'undefined');
+
+ assert.strictEqual(resultPromise instanceof Promise, false);
+ assert.strictEqual(typeof resultPromise.then, 'function');
+
+ assert.strictEqual(await resultPromise.assert.equals(true), true);
+ assert.strictEqual(await resultPromise.assert.not.equals(false), true);
+ });
+});
diff --git a/types/tests/webElement.test-d.ts b/types/tests/webElement.test-d.ts
index 1ddcc172b..ff3472e9f 100644
--- a/types/tests/webElement.test-d.ts
+++ b/types/tests/webElement.test-d.ts
@@ -163,6 +163,7 @@ describe('new element() api', function () {
expectType>(elem.isSelected());
expectType>(elem.isVisible());
expectType>(elem.isDisplayed());
+ expectType>(elem.isActive());
expectType>(elem.getRect());
expectType>(elem.rect());
diff --git a/types/web-element.d.ts b/types/web-element.d.ts
index 426778068..09df750c0 100644
--- a/types/web-element.d.ts
+++ b/types/web-element.d.ts
@@ -216,6 +216,8 @@ export interface ScopedElement extends Element, PromiseLike {
isVisible(): ElementValue;
isDisplayed(): ElementValue;
+
+ isActive(): ElementValue;
}
type WaitUntilOptions = {