From e8db4f1e09ff7dba5390854c4f7a2f570f66e42c Mon Sep 17 00:00:00 2001 From: Ruslan Hrabovyi Date: Wed, 1 Nov 2023 00:54:38 +0100 Subject: [PATCH] replace `jQuery.val(` with local implementation --- addon/src/properties/value.js | 31 +- addon/types.d.ts | 2 +- .../unit/-private/properties/value-test.ts | 424 ++++++++++++++++++ 3 files changed, 453 insertions(+), 4 deletions(-) diff --git a/addon/src/properties/value.js b/addon/src/properties/value.js index 95db38d1..5ea1a5c9 100644 --- a/addon/src/properties/value.js +++ b/addon/src/properties/value.js @@ -1,4 +1,3 @@ -import { $ } from '../-private/jquery'; import { findOne } from '../-private/finders'; import { getter } from '../macros/index'; @@ -83,7 +82,33 @@ export function value(selector, userOptions = {}) { const element = findOne(this, selector, options); return element.hasAttribute('contenteditable') - ? $(element).html() - : $(element).val(); + ? element.innerHTML + : getValue(element); }); } + +function getValue(element) { + const { value } = element; + if (value !== undefined && element.tagName.toLowerCase() === 'select') { + return selectValue(element); + } + + return element.value; +} + +function selectValue(element) { + const selectedOptions = Array.from(element.selectedOptions).filter( + (option) => + !option.disabled && + (option.parentNode.tagName.toLowerCase() !== 'optgroup' || + !option.parentNode.disabled) + ); + + if (element.multiple) { + return selectedOptions.map((option) => option.value); + } else if (selectedOptions.length === 0) { + return null; + } + + return element.value; +} diff --git a/addon/types.d.ts b/addon/types.d.ts index bb4a185e..0643e7d1 100644 --- a/addon/types.d.ts +++ b/addon/types.d.ts @@ -19,7 +19,7 @@ declare module 'ember-cli-page-object' { export function isHidden(scope?: string, options?: FindOptions): GetterDescriptor; export function isPresent(scope?: string, options?: FindOptions): GetterDescriptor; export function text(scope?: string, options?: FindOptions & { normalize?: boolean }): GetterDescriptor; - export function value(scope?: string, options?: FindOptions): GetterDescriptor; + export function value(scope?: string, options?: FindOptions): GetterDescriptor; export function property(name: string, scope?: string, options?: FindOptions): GetterDescriptor; export function hasClass(className: string, scope?: string, options?: FindOptions): GetterDescriptor; export function notHasClass(className: string, scope?: string, options?: FindOptions): GetterDescriptor; diff --git a/test-app/tests/unit/-private/properties/value-test.ts b/test-app/tests/unit/-private/properties/value-test.ts index 97f3df5d..f868f131 100644 --- a/test-app/tests/unit/-private/properties/value-test.ts +++ b/test-app/tests/unit/-private/properties/value-test.ts @@ -1,6 +1,8 @@ import { create, value } from 'ember-cli-page-object'; import { setupRenderingTest, TestContext } from '../../../helpers'; import { module, test } from 'qunit'; +import { render } from '@ember/test-helpers'; +import hbs from 'htmlbars-inline-precompile'; module('value', function(hooks) { setupRenderingTest(hooks); @@ -141,4 +143,426 @@ module('value', function(hooks) { assert.equal(page.foo, 'lorem'); }); + + module('jquery compatibility', function () { + module('input', function (hooks) { + + test('no value', async function (this: TestContext, assert) { + let page = create({ + value: value('input') + }); + + await render(hbs``); + + assert.strictEqual(page.value, ''); + }); + + test('with value', async function (this: TestContext, assert) { + let page = create({ + value: value('input') + }); + + this.set('value', 'lorem'); + await render(hbs``); + + assert.strictEqual(page.value, 'lorem'); + + this.set('value', null); + + assert.strictEqual(page.value, ''); + }); + + test('disabled', async function (this: TestContext, assert) { + let page = create({ + value: value('input') + }); + + this.set('value', 'lorem'); + await render(hbs``); + + assert.strictEqual(page.value, 'lorem'); + }); + }); + + module('checkbox', function () { + test('no value', async function (this: TestContext, assert) { + let page = create({ + value: value('input') + }); + + await render(hbs``); + + assert.strictEqual(page.value, 'on'); + + this.set('checked', ''); + + assert.strictEqual(page.value, 'on'); + }); + + test('with value', async function (this: TestContext, assert) { + let page = create({ + value: value('input') + }); + + this.set('value', 'lorem'); + await render(hbs``); + + assert.strictEqual(page.value, 'lorem'); + + this.set('value', null); + + assert.strictEqual(page.value, ''); + + this.set('checked', ''); + + assert.strictEqual(page.value, ''); + }); + + test('disabled', async function (this: TestContext, assert) { + let page = create({ + value: value('input') + }); + + this.set('value', 'lorem'); + await render(hbs``); + + assert.strictEqual(page.value, 'lorem'); + + this.set('checked', ''); + + assert.strictEqual(page.value, 'lorem'); + }); + }); + + module('select', function () { + test('selected with [value]', async function (this: TestContext, assert) { + let page = create({ + value: value('select') + }); + + await this.createTemplate(``); + + assert.strictEqual(page.value, "2"); + }); + + test('[disabled] selected option', async function (this: TestContext, assert) { + let page = create({ + value: value('select') + }); + + await this.createTemplate(``); + + assert.strictEqual(page.value, "2"); + }); + + test('selected option[disabled] ', async function (this: TestContext, assert) { + let page = create({ + value: value('select') + }); + + await this.createTemplate(``); + + assert.strictEqual(page.value, null); + }); + + test('no selected with [value]', async function (this: TestContext, assert) { + let page = create({ + value: value('select') + }); + + await this.createTemplate(``); + + assert.strictEqual(page.value, '1'); + }); + + test('selected with no [value]', async function (this: TestContext, assert) { + let page = create({ + value: value('select') + }); + + await this.createTemplate(``); + + assert.strictEqual(page.value, 'Ipsum'); + }); + + test('not selected with no [value]', async function (this: TestContext, assert) { + let page = create({ + value: value('select') + }); + + await this.createTemplate(``); + + assert.strictEqual(page.value, 'lorem'); + }); + + module('optgroup', function () { + test('selected with [value]', async function (this: TestContext, assert) { + let page = create({ + value: value('select') + }); + + await this.createTemplate(``); + + assert.strictEqual(page.value, "2"); + }); + + test('[disabled] selected with [value]', async function (this: TestContext, assert) { + let page = create({ + value: value('select') + }); + + await this.createTemplate(``); + + assert.strictEqual(page.value, null); + }); + + test('selected with [value][disabled]', async function (this: TestContext, assert) { + let page = create({ + value: value('select') + }); + + await this.createTemplate(``); + + assert.strictEqual(page.value, null); + }); + }); + }); + + module('select[multiple]', function () { + test('selected with [value]', async function (this: TestContext, assert) { + let page = create({ + value: value('select') + }); + + await this.createTemplate(``); + + assert.deepEqual(page.value, ["2"]); + }); + + test('[disabled] selected option', async function (this: TestContext, assert) { + let page = create({ + value: value('select') + }); + + await this.createTemplate(``); + + assert.deepEqual(page.value, ["2"]); + }); + + test('selected option[disabled] ', async function (this: TestContext, assert) { + let page = create({ + value: value('select') + }); + + await this.createTemplate(``); + + assert.deepEqual(page.value, [] as string[]); + }); + + test('no selected with [value]', async function (this: TestContext, assert) { + let page = create({ + value: value('select') + }); + + await this.createTemplate(``); + + assert.deepEqual(page.value, [] as string[]); + }); + + test('selected with no [value]', async function (this: TestContext, assert) { + let page = create({ + value: value('select') + }); + + await this.createTemplate(``); + + assert.deepEqual(page.value, ['Ipsum']); + }); + + test('not selected with no [value]', async function (this: TestContext, assert) { + let page = create({ + value: value('select') + }); + + await this.createTemplate(``); + + assert.deepEqual(page.value, [] as string[]); + }); + + module('optgroup', function () { + test('selected with [value]', async function (this: TestContext, assert) { + let page = create({ + value: value('select') + }); + + await this.createTemplate(``); + + assert.strictEqual(page.value, "2"); + }); + + test('[disabled] selected with [value]', async function (this: TestContext, assert) { + let page = create({ + value: value('select') + }); + + await this.createTemplate(``); + + assert.strictEqual(page.value, null); + }); + + test('selected with [value][disabled]', async function (this: TestContext, assert) { + let page = create({ + value: value('select') + }); + + await this.createTemplate(``); + + assert.strictEqual(page.value, null); + }); + }); + }); + + module('option', function () { + test('selected', async function (this: TestContext, assert) { + let page = create({ + value: value('option[selected]') + }); + + await this.createTemplate(``); + + assert.strictEqual(page.value, "2"); + }); + + test('not selected with [value]', async function (this: TestContext, assert) { + let page = create({ + value: value('option[value=1]') + }); + + await this.createTemplate(``); + + assert.strictEqual(page.value, "1"); + }); + + test('selected with no [value]', async function (this: TestContext, assert) { + let page = create({ + value: value('#secondOption') + }); + + await this.createTemplate(``); + + assert.strictEqual(page.value, "Ipsum"); + }); + + test('not selected with no [value]', async function (this: TestContext, assert) { + let page = create({ + value: value('#secondOption') + }); + + await this.createTemplate(``); + + assert.strictEqual(page.value, "Ipsum"); + }); + }); + + }); });