Skip to content

Commit

Permalink
Implement hasProperty() assertion
Browse files Browse the repository at this point in the history
  • Loading branch information
Turbo87 committed Feb 2, 2020
1 parent 7031f63 commit 5f046e7
Show file tree
Hide file tree
Showing 2 changed files with 179 additions and 0 deletions.
128 changes: 128 additions & 0 deletions lib/__tests__/has-property.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/* eslint-env jest */

import TestAssertions from '../helpers/test-assertions';

describe('assert.dom(...).hasProperty()', () => {
let assert: TestAssertions;

beforeEach(() => {
assert = new TestAssertions();

document.body.innerHTML = '<input type="password">';
});

describe('string expected', () => {
test('succeeds for correct name and value', () => {
assert.dom('input').hasProperty('type', 'password');
assert.dom(document.querySelector('input')).hasProperty('type', 'password');

expect(assert.results).toEqual([
{
actual: 'Element input has property "type" with value "password"',
expected: 'Element input has property "type" with value "password"',
message: 'Element input has property "type" with value "password"',
result: true,
},
{
actual: 'Element input[type="password"] has property "type" with value "password"',
expected: 'Element input[type="password"] has property "type" with value "password"',
message: 'Element input[type="password"] has property "type" with value "password"',
result: true,
},
]);
});

test('fails for wrong value', () => {
assert.dom('input').hasProperty('type', 'text');
assert.dom(document.querySelector('input')).hasProperty('type', 'text');

expect(assert.results).toEqual([
{
actual: 'Element input has property "type" with value "password"',
expected: 'Element input has property "type" with value "text"',
message: 'Element input has property "type" with value "text"',
result: false,
},
{
actual: 'Element input[type="password"] has property "type" with value "password"',
expected: 'Element input[type="password"] has property "type" with value "text"',
message: 'Element input[type="password"] has property "type" with value "text"',
result: false,
},
]);
});
});

describe('regex expected', () => {
test('succeeds for matching name and value', () => {
assert.dom('input').hasProperty('type', /^pass/);
assert.dom(document.querySelector('input')).hasProperty('type', /^pass/);

expect(assert.results).toEqual([
{
actual: 'Element input has property "type" with value "password"',
expected: 'Element input has property "type" with value matching /^pass/',
message: 'Element input has property "type" with value matching /^pass/',
result: true,
},
{
actual: 'Element input[type="password"] has property "type" with value "password"',
expected:
'Element input[type="password"] has property "type" with value matching /^pass/',
message: 'Element input[type="password"] has property "type" with value matching /^pass/',
result: true,
},
]);
});

test('fails for wrong value', () => {
assert.dom('input').hasProperty('type', /mail$/);
assert.dom(document.querySelector('input')).hasProperty('type', /mail$/);

expect(assert.results).toEqual([
{
actual: 'Element input has property "type" with value "password"',
expected: 'Element input has property "type" with value matching /mail$/',
message: 'Element input has property "type" with value matching /mail$/',
result: false,
},
{
actual: 'Element input[type="password"] has property "type" with value "password"',
expected:
'Element input[type="password"] has property "type" with value matching /mail$/',
message: 'Element input[type="password"] has property "type" with value matching /mail$/',
result: false,
},
]);
});
});

test('fails for missing element', () => {
assert.dom('#missing').hasProperty('foo', 'bar');

expect(assert.results).toEqual([
{
message: 'Element #missing should exist',
result: false,
},
]);
});

test('throws for unexpected parameter types', () => {
//@ts-ignore -- These assertions are for JavaScript users who don't have type checking
expect(() => assert.dom(5).hasProperty('foo', 'bar')).toThrow('Unexpected Parameter: 5');
//@ts-ignore
expect(() => assert.dom(true).hasProperty('foo', 'bar')).toThrow('Unexpected Parameter: true');
expect(() => assert.dom(undefined).hasProperty('foo', 'bar')).toThrow(
'Unexpected Parameter: undefined'
);
//@ts-ignore
expect(() => assert.dom({}).hasProperty('foo', 'bar')).toThrow(
'Unexpected Parameter: [object Object]'
);
//@ts-ignore
expect(() => assert.dom(document).hasProperty('foo', 'bar')).toThrow(
'Unexpected Parameter: [object Document]'
);
});
});
51 changes: 51 additions & 0 deletions lib/assertions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,57 @@ export default class DOMAssertions {
this.doesNotHaveAttribute(name, message);
}

/**
* Assert that the {@link HTMLElement} has a property with the provided `name`
* and checks if the property `value` matches the provided text or regular
* expression.
*
* @param {string} name
* @param {string|RegExp} value
* @param {string?} message
*
* @example
* assert.dom('input.password-input').hasAttribute('type', 'password');
*
* @see {@link #doesNotHaveProperty}
*/
hasProperty(name: string, value: string | RegExp, message?: string): void {
let element = this.findTargetElement();
if (!element) return;

let description = this.targetDescription;

let actualValue = element[name as keyof Element];

if (value instanceof RegExp) {
let result = value.test(String(actualValue));
let expected = `Element ${description} has property "${name}" with value matching ${value}`;
let actual = `Element ${description} has property "${name}" with value ${JSON.stringify(
actualValue
)}`;

if (!message) {
message = expected;
}

this.pushResult({ result, actual, expected, message });
} else {
let result = value === actualValue;
let expected = `Element ${description} has property "${name}" with value ${JSON.stringify(
value
)}`;
let actual = `Element ${description} has property "${name}" with value ${JSON.stringify(
actualValue
)}`;

if (!message) {
message = expected;
}

this.pushResult({ result, actual, expected, message });
}
}

/**
* Assert that the {@link HTMLElement} or an {@link HTMLElement} matching the
* `selector` is disabled.
Expand Down

0 comments on commit 5f046e7

Please sign in to comment.