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 = {