diff --git a/API.md b/API.md
index 80511dc03..bec54c32a 100644
--- a/API.md
+++ b/API.md
@@ -224,6 +224,26 @@ attribute.
assert.dom('#title').includesText('Welcome');
```
+### doesNotIncludeText
+
+Assert that the text of the [HTMLElement][] or an [HTMLElement][]
+matching the `selector` does not include the given `text`, using the
+[`textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent)
+attribute.
+
+**Aliases:** `doesNotContainText`, `doesNotHaveTextContaining`
+
+**Parameters**
+
+- `text` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)**
+- `message` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?**
+
+**Examples**
+
+```javascript
+assert.dom('#title').doesNotIncludeText('Welcome');
+```
+
### hasValue
- **See: [#hasAnyValue](#hasanyvalue)**
diff --git a/lib/__tests__/does-not-include-text.js b/lib/__tests__/does-not-include-text.js
new file mode 100644
index 000000000..0b10ee9dc
--- /dev/null
+++ b/lib/__tests__/does-not-include-text.js
@@ -0,0 +1,109 @@
+/* eslint-env jest */
+
+import TestAssertions from "../helpers/test-assertions";
+
+describe('assert.dom(...).doesNotIncludeText()', () => {
+ let assert;
+
+ beforeEach(() => {
+ assert = new TestAssertions();
+ });
+
+ test('with custom message', () => {
+ document.body.innerHTML = '
foo
bar';
+
+ assert.dom('h1').doesNotIncludeText('baz', 'bing');
+
+ expect(assert.results).toEqual([{
+ actual: "Element h1 does not include text \"baz\"",
+ expected: "Element h1 does not include text \"baz\"",
+ message: 'bing',
+ result: true,
+ }]);
+ });
+
+ describe('with HTMLElement', () => {
+ let element;
+
+ beforeEach(() => {
+ document.body.innerHTML = 'foo
bar';
+ element = document.querySelector('h1');
+ });
+
+ test('succeeds for correct content', () => {
+ assert.dom(element).doesNotIncludeText('baz');
+
+ expect(assert.results).toEqual([{
+ actual: "Element h1.baz does not include text \"baz\"",
+ expected: "Element h1.baz does not include text \"baz\"",
+ message: "Element h1.baz does not include text \"baz\"",
+ result: true,
+ }]);
+ });
+
+ test('fails for wrong content', () => {
+ assert.dom(element).doesNotIncludeText('foo');
+
+ expect(assert.results).toEqual([{
+ actual: 'Element h1.baz includes text "foo"',
+ expected: 'Element h1.baz does not include text "foo"',
+ message: 'Element h1.baz does not include text "foo"',
+ result: false,
+ }]);
+ });
+
+ test('fails for missing element', () => {
+ assert.dom(null).doesNotIncludeText('foo');
+
+ expect(assert.results).toEqual([{
+ message: 'Element exists',
+ result: false,
+ }]);
+ });
+ });
+
+ describe('with selector', () => {
+ beforeEach(() => {
+ document.body.innerHTML = 'foo
bar';
+ });
+
+ test('succeeds for correct content', () => {
+ assert.dom('h1').doesNotIncludeText('bar');
+
+ expect(assert.results).toEqual([{
+ actual: 'Element h1 does not include text "bar"',
+ expected: 'Element h1 does not include text "bar"',
+ message: 'Element h1 does not include text "bar"',
+ result: true,
+ }]);
+ });
+
+ test('fails for wrong content', () => {
+ assert.dom('h1').doesNotIncludeText('foo');
+
+ expect(assert.results).toEqual([{
+ actual: 'Element h1 includes text "foo"',
+ expected: 'Element h1 does not include text "foo"',
+ message: 'Element h1 does not include text "foo"',
+ result: false,
+ }]);
+ });
+
+ test('fails for missing element', () => {
+ assert.dom('h2').doesNotIncludeText('foo');
+
+ expect(assert.results).toEqual([{
+ message: 'Element h2 exists',
+ result: false,
+ }]);
+ });
+ });
+
+ test('throws for unexpected parameter types', () => {
+ expect(() => assert.dom(5).doesNotIncludeText('foo')).toThrow('Unexpected Parameter: 5');
+ expect(() => assert.dom(true).doesNotIncludeText('foo')).toThrow('Unexpected Parameter: true');
+ expect(() => assert.dom(undefined).doesNotIncludeText('foo')).toThrow('Unexpected Parameter: undefined');
+ expect(() => assert.dom({}).doesNotIncludeText('foo')).toThrow('Unexpected Parameter: [object Object]');
+ expect(() => assert.dom(document).doesNotIncludeText('foo')).toThrow('Unexpected Parameter: [object HTMLDocument]');
+ });
+});
diff --git a/lib/assertions.js b/lib/assertions.js
index 6f252dd7b..d583fee0d 100644
--- a/lib/assertions.js
+++ b/lib/assertions.js
@@ -327,6 +327,47 @@ export default class DOMAssertions {
this.includesText(expected, message);
}
+ /**
+ * Assert that the text of the [HTMLElement][] or an [HTMLElement][]
+ * matching the `selector` does not include the given `text`, using the
+ * [`textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent)
+ * attribute.
+ *
+ * **Aliases:** `doesNotContainText`, `doesNotHaveTextContaining`
+ *
+ * @param {string} text
+ * @param {string?} message
+ *
+ * @example
+ * assert.dom('#title').doesNotIncludeText('Welcome');
+ */
+ doesNotIncludeText(text, message) {
+ let element = this.findTargetElement();
+ if (!element) return;
+
+ let result = element.textContent.indexOf(text) === -1;
+ let expected = `Element ${this.targetDescription} does not include text "${text}"`;
+ let actual = expected;
+
+ if (!result) {
+ actual = `Element ${this.targetDescription} includes text "${text}"`;
+ }
+
+ if (!message) {
+ message = expected;
+ }
+
+ this.pushResult({ result, actual, expected, message });
+ }
+
+ doesNotContainText(unexpected, message) {
+ this.doesNotIncludeText(unexpected, message);
+ }
+
+ doesNotHaveTextContaining(unexpected, message) {
+ this.doesNotIncludeText(unexpected, message);
+ }
+
/**
* Assert that the `value` property of an [HTMLInputElement][] matches
* the `expected` text or regular expression.