@mui/internal-test-utils 2.0.14 → 2.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{src/chai.types.ts → chai.types.d.ts} +7 -40
- package/chai.types.js +5 -0
- package/chaiPlugin.d.ts +4 -0
- package/chaiPlugin.js +287 -0
- package/{build/components.d.ts → components.d.ts} +18 -19
- package/components.js +64 -0
- package/createDOM.d.ts +2 -0
- package/{src/createDOM.js → createDOM.js} +17 -35
- package/createDescribe.d.ts +7 -0
- package/createDescribe.js +26 -0
- package/createRenderer.d.ts +214 -0
- package/createRenderer.js +428 -0
- package/createRenderer.test.d.ts +1 -0
- package/describeConformance.d.ts +200 -0
- package/describeConformance.js +1038 -0
- package/env.d.ts +1 -0
- package/env.js +11 -0
- package/esm/chai.types.d.ts +74 -0
- package/esm/chai.types.js +3 -0
- package/esm/chaiPlugin.d.ts +4 -0
- package/esm/chaiPlugin.js +281 -0
- package/esm/components.d.ts +35 -0
- package/esm/components.js +56 -0
- package/esm/createDOM.d.ts +2 -0
- package/esm/createDOM.js +47 -0
- package/esm/createDescribe.d.ts +7 -0
- package/esm/createDescribe.js +19 -0
- package/esm/createRenderer.d.ts +214 -0
- package/esm/createRenderer.js +390 -0
- package/esm/createRenderer.test.d.ts +1 -0
- package/esm/describeConformance.d.ts +200 -0
- package/esm/describeConformance.js +1024 -0
- package/esm/env.d.ts +1 -0
- package/esm/env.js +5 -0
- package/{build → esm}/fireDiscreteEvent.d.ts +1 -2
- package/{src/fireDiscreteEvent.ts → esm/fireDiscreteEvent.js} +10 -18
- package/esm/flushMicrotasks.d.ts +1 -0
- package/{src/flushMicrotasks.ts → esm/flushMicrotasks.js} +2 -3
- package/{build → esm}/focusVisible.d.ts +1 -2
- package/{src/focusVisible.ts → esm/focusVisible.js} +10 -9
- package/esm/index.d.ts +18 -0
- package/esm/index.js +27 -0
- package/esm/init.d.ts +1 -0
- package/{src → esm}/init.js +4 -2
- package/esm/initMatchers.d.ts +1 -0
- package/esm/initMatchers.js +6 -0
- package/esm/initMatchers.test.d.ts +1 -0
- package/esm/initPlaywrightMatchers.d.ts +24 -0
- package/esm/initPlaywrightMatchers.js +40 -0
- package/esm/package.json +1 -0
- package/esm/reactMajor.d.ts +2 -0
- package/esm/reactMajor.js +2 -0
- package/esm/setup.d.ts +1 -0
- package/{src → esm}/setup.js +2 -4
- package/esm/setupVitest.d.ts +1 -0
- package/esm/setupVitest.js +28 -0
- package/esm/setupVitestBrowser.d.ts +1 -0
- package/esm/setupVitestBrowser.js +30 -0
- package/fireDiscreteEvent.d.ts +6 -0
- package/fireDiscreteEvent.js +79 -0
- package/flushMicrotasks.d.ts +1 -0
- package/flushMicrotasks.js +10 -0
- package/focusVisible.d.ts +7 -0
- package/focusVisible.js +44 -0
- package/index.d.ts +18 -0
- package/index.js +139 -0
- package/init.d.ts +1 -0
- package/init.js +15 -0
- package/initMatchers.d.ts +1 -0
- package/initMatchers.js +10 -0
- package/initMatchers.test.d.ts +1 -0
- package/initPlaywrightMatchers.d.ts +24 -0
- package/initPlaywrightMatchers.js +42 -0
- package/package.json +89 -46
- package/reactMajor.d.ts +2 -0
- package/reactMajor.js +9 -0
- package/setup.d.ts +1 -0
- package/setup.js +10 -0
- package/setupVitest.d.ts +1 -0
- package/setupVitest.js +32 -0
- package/setupVitestBrowser.d.ts +1 -0
- package/setupVitestBrowser.js +34 -0
- package/build/.tsbuildinfo +0 -1
- package/build/KarmaReporterReactProfiler.d.ts +0 -51
- package/build/KarmaReporterReactProfiler.d.ts.map +0 -1
- package/build/KarmaReporterReactProfiler.js +0 -66
- package/build/KarmaReporterReactProfiler.js.map +0 -1
- package/build/chai.types.d.ts +0 -75
- package/build/chai.types.d.ts.map +0 -1
- package/build/chai.types.js +0 -3
- package/build/chai.types.js.map +0 -1
- package/build/chaiPlugin.d.ts +0 -5
- package/build/chaiPlugin.d.ts.map +0 -1
- package/build/chaiPlugin.js +0 -417
- package/build/chaiPlugin.js.map +0 -1
- package/build/components.d.ts.map +0 -1
- package/build/components.js +0 -88
- package/build/components.js.map +0 -1
- package/build/createDOM.d.ts +0 -3
- package/build/createDOM.d.ts.map +0 -1
- package/build/createDOM.js +0 -60
- package/build/createDOM.js.map +0 -1
- package/build/createDescribe.d.ts +0 -8
- package/build/createDescribe.d.ts.map +0 -1
- package/build/createDescribe.js +0 -22
- package/build/createDescribe.js.map +0 -1
- package/build/createRenderer.d.ts +0 -215
- package/build/createRenderer.d.ts.map +0 -1
- package/build/createRenderer.js +0 -565
- package/build/createRenderer.js.map +0 -1
- package/build/createRenderer.test.d.ts +0 -2
- package/build/createRenderer.test.d.ts.map +0 -1
- package/build/createRenderer.test.js +0 -58
- package/build/createRenderer.test.js.map +0 -1
- package/build/describeConformance.d.ts +0 -201
- package/build/describeConformance.d.ts.map +0 -1
- package/build/describeConformance.js +0 -859
- package/build/describeConformance.js.map +0 -1
- package/build/describeSkipIf.d.ts +0 -4
- package/build/describeSkipIf.d.ts.map +0 -1
- package/build/describeSkipIf.js +0 -10
- package/build/describeSkipIf.js.map +0 -1
- package/build/fireDiscreteEvent.d.ts.map +0 -1
- package/build/fireDiscreteEvent.js +0 -77
- package/build/fireDiscreteEvent.js.map +0 -1
- package/build/flushMicrotasks.d.ts +0 -2
- package/build/flushMicrotasks.d.ts.map +0 -1
- package/build/flushMicrotasks.js +0 -8
- package/build/flushMicrotasks.js.map +0 -1
- package/build/focusVisible.d.ts.map +0 -1
- package/build/focusVisible.js +0 -38
- package/build/focusVisible.js.map +0 -1
- package/build/index.d.ts +0 -18
- package/build/index.d.ts.map +0 -1
- package/build/index.js +0 -68
- package/build/index.js.map +0 -1
- package/build/init.d.ts +0 -2
- package/build/init.d.ts.map +0 -1
- package/build/init.js +0 -46
- package/build/init.js.map +0 -1
- package/build/initMatchers.d.ts +0 -2
- package/build/initMatchers.d.ts.map +0 -1
- package/build/initMatchers.js +0 -45
- package/build/initMatchers.js.map +0 -1
- package/build/initMatchers.test.d.ts +0 -2
- package/build/initMatchers.test.d.ts.map +0 -1
- package/build/initMatchers.test.js +0 -101
- package/build/initMatchers.test.js.map +0 -1
- package/build/initPlaywrightMatchers.d.ts +0 -25
- package/build/initPlaywrightMatchers.d.ts.map +0 -1
- package/build/initPlaywrightMatchers.js +0 -73
- package/build/initPlaywrightMatchers.js.map +0 -1
- package/build/mochaHooks.d.ts +0 -24
- package/build/mochaHooks.d.ts.map +0 -1
- package/build/mochaHooks.js +0 -165
- package/build/mochaHooks.js.map +0 -1
- package/build/mochaHooks.test.d.ts +0 -2
- package/build/mochaHooks.test.d.ts.map +0 -1
- package/build/mochaHooks.test.js +0 -127
- package/build/mochaHooks.test.js.map +0 -1
- package/build/reactMajor.d.ts +0 -3
- package/build/reactMajor.d.ts.map +0 -1
- package/build/reactMajor.js +0 -38
- package/build/reactMajor.js.map +0 -1
- package/build/setup.d.ts +0 -2
- package/build/setup.d.ts.map +0 -1
- package/build/setup.js +0 -10
- package/build/setup.js.map +0 -1
- package/build/setupBabel.d.ts +0 -2
- package/build/setupBabel.d.ts.map +0 -1
- package/build/setupBabel.js +0 -5
- package/build/setupBabel.js.map +0 -1
- package/build/setupBabelPlaywright.d.ts +0 -2
- package/build/setupBabelPlaywright.d.ts.map +0 -1
- package/build/setupBabelPlaywright.js +0 -14
- package/build/setupBabelPlaywright.js.map +0 -1
- package/build/setupJSDOM.d.ts +0 -7
- package/build/setupJSDOM.d.ts.map +0 -1
- package/build/setupJSDOM.js +0 -17
- package/build/setupJSDOM.js.map +0 -1
- package/build/setupKarma.d.ts +0 -2
- package/build/setupKarma.d.ts.map +0 -1
- package/build/setupKarma.js +0 -56
- package/build/setupKarma.js.map +0 -1
- package/build/setupVitest.d.ts +0 -2
- package/build/setupVitest.d.ts.map +0 -1
- package/build/setupVitest.js +0 -131
- package/build/setupVitest.js.map +0 -1
- package/src/KarmaReporterReactProfiler.js +0 -82
- package/src/chai-augmentation.d.ts +0 -8
- package/src/chaiPlugin.ts +0 -516
- package/src/components.tsx +0 -61
- package/src/createDOM.d.ts +0 -9
- package/src/createDescribe.ts +0 -31
- package/src/createRenderer.test.js +0 -31
- package/src/createRenderer.tsx +0 -809
- package/src/describeConformance.tsx +0 -1257
- package/src/describeSkipIf.tsx +0 -11
- package/src/index.ts +0 -25
- package/src/initMatchers.test.js +0 -124
- package/src/initMatchers.ts +0 -7
- package/src/initPlaywrightMatchers.ts +0 -101
- package/src/mochaHooks.js +0 -200
- package/src/mochaHooks.test.js +0 -115
- package/src/reactMajor.ts +0 -3
- package/src/setupBabel.js +0 -3
- package/src/setupBabelPlaywright.js +0 -13
- package/src/setupJSDOM.js +0 -20
- package/src/setupKarma.js +0 -65
- package/src/setupVitest.ts +0 -117
- package/tsconfig.build.json +0 -16
- package/tsconfig.json +0 -17
package/src/describeSkipIf.tsx
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { PendingSuiteFunction } from 'mocha';
|
|
2
|
-
|
|
3
|
-
// Shim for vitest describe.skipIf to be able to run mocha and vitest side-by-side
|
|
4
|
-
// TODO: Remove after migration to vitest is complete
|
|
5
|
-
const describeSkipIf: (condition: boolean) => PendingSuiteFunction =
|
|
6
|
-
(describe as any).skipIf ??
|
|
7
|
-
function describeSkipIf(condition: boolean) {
|
|
8
|
-
return condition ? describe.skip : describe;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export default describeSkipIf;
|
package/src/index.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
|
|
3
|
-
export * from './components';
|
|
4
|
-
export { default as describeConformance } from './describeConformance';
|
|
5
|
-
export * from './describeConformance';
|
|
6
|
-
export { default as createDescribe } from './createDescribe';
|
|
7
|
-
export * from './createRenderer';
|
|
8
|
-
export {
|
|
9
|
-
default as focusVisible,
|
|
10
|
-
simulatePointerDevice,
|
|
11
|
-
simulateKeyboardDevice,
|
|
12
|
-
programmaticFocusTriggersFocusVisible,
|
|
13
|
-
} from './focusVisible';
|
|
14
|
-
export {} from './initMatchers';
|
|
15
|
-
export * as fireDiscreteEvent from './fireDiscreteEvent';
|
|
16
|
-
export { default as flushMicrotasks } from './flushMicrotasks';
|
|
17
|
-
export { default as reactMajor } from './reactMajor';
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Set to true if console logs during [lifecycles that are invoked twice in `React.StrictMode`](https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects) are suppressed.
|
|
21
|
-
* Useful for asserting on `console.warn` or `console.error` via `toErrorDev()`.
|
|
22
|
-
* TODO: Refactor to use reactMajor when fixing the React 17 cron test.
|
|
23
|
-
* https://github.com/mui/material-ui/issues/43153
|
|
24
|
-
*/
|
|
25
|
-
export const strictModeDoubleLoggingSuppressed = React.version.startsWith('17');
|
package/src/initMatchers.test.js
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import { expect } from 'chai';
|
|
2
|
-
import { createSandbox } from 'sinon';
|
|
3
|
-
|
|
4
|
-
describe('custom matchers', () => {
|
|
5
|
-
const consoleSandbox = createSandbox();
|
|
6
|
-
|
|
7
|
-
beforeEach(() => {
|
|
8
|
-
// otherwise our global setup throws on unexpected calls in afterEach
|
|
9
|
-
consoleSandbox.stub(console, 'warn');
|
|
10
|
-
consoleSandbox.stub(console, 'error');
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
afterEach(() => {
|
|
14
|
-
consoleSandbox.restore();
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
describe('toErrorDev()', () => {
|
|
18
|
-
it('passes if the message is exactly the same', () => {
|
|
19
|
-
expect(() => console.error('expected message')).toErrorDev('expected message');
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
it('passes if the message is a subset', () => {
|
|
23
|
-
expect(() => console.error('expected message')).toErrorDev('pected messa');
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it('passes if multiple messages are expected', () => {
|
|
27
|
-
expect(() => {
|
|
28
|
-
console.error('expected message');
|
|
29
|
-
console.error('another message');
|
|
30
|
-
}).toErrorDev(['expected message', 'another message']);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it("fails if an expected console.error call wasn't recorded with a useful stacktrace", () => {
|
|
34
|
-
let caughtError;
|
|
35
|
-
try {
|
|
36
|
-
console.error('expected message');
|
|
37
|
-
expect(() => {}).toErrorDev('expected message');
|
|
38
|
-
} catch (error) {
|
|
39
|
-
caughtError = error;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
expect(caughtError).to.have.property('stack');
|
|
43
|
-
expect(caughtError.stack).to.include(
|
|
44
|
-
'Could not match the following console.error calls. ' +
|
|
45
|
-
"Make sure previous actions didn't call console.error by wrapping them in expect(() => {}).not.toErrorDev(): \n\n" +
|
|
46
|
-
' - "expected message"\n',
|
|
47
|
-
);
|
|
48
|
-
// check that the top stackframe points to this test
|
|
49
|
-
// if this test is moved to another file the next assertion fails
|
|
50
|
-
expect(caughtError.stack).to.match(
|
|
51
|
-
/- "expected message"\s+at .*\/initMatchers\.test\.js:\d+:\d+/,
|
|
52
|
-
);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('is case sensitive', () => {
|
|
56
|
-
let caughtError;
|
|
57
|
-
try {
|
|
58
|
-
expect(() => console.error('expected Message')).toErrorDev('expected message');
|
|
59
|
-
} catch (error) {
|
|
60
|
-
caughtError = error;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
expect(caughtError).to.have.property('stack');
|
|
64
|
-
expect(caughtError.stack).to.include(
|
|
65
|
-
'Recorded unexpected console.error calls: \n\n' +
|
|
66
|
-
' - Expected #1 "expected message" to be included in \n' +
|
|
67
|
-
'"expected Message"\n',
|
|
68
|
-
);
|
|
69
|
-
// check that the top stackframe points to this test
|
|
70
|
-
// if this test is moved to another file the next assertion fails
|
|
71
|
-
expect(caughtError.stack).to.match(
|
|
72
|
-
/"expected Message"\s+at .*\/initMatchers\.test\.js:\d+:\d+/,
|
|
73
|
-
);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it('fails if the order of calls does not match', () => {
|
|
77
|
-
expect(() => {
|
|
78
|
-
expect(() => {
|
|
79
|
-
console.error('another message');
|
|
80
|
-
console.error('expected message');
|
|
81
|
-
}).toErrorDev(['expected message', 'another message']);
|
|
82
|
-
}).to.throw('Recorded unexpected console.error calls');
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it('fails if there are fewer messages than expected', () => {
|
|
86
|
-
expect(() => {
|
|
87
|
-
expect(() => {
|
|
88
|
-
console.error('expected message');
|
|
89
|
-
}).toErrorDev(['expected message', 'another message']);
|
|
90
|
-
}).to.throw('Could not match the following console.error calls');
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
it('passes if no messages were recorded if expected', () => {
|
|
94
|
-
expect(() => {}).not.toErrorDev();
|
|
95
|
-
expect(() => {}).not.toErrorDev([]);
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
it('fails if no arguments are used as a way of negating', () => {
|
|
99
|
-
expect(() => {
|
|
100
|
-
expect(() => {}).toErrorDev();
|
|
101
|
-
}).to.throw(
|
|
102
|
-
"Expected to call console.error but didn't provide messages. " +
|
|
103
|
-
"If you don't expect any messages prefer `expect().not.toErrorDev();",
|
|
104
|
-
);
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
it('fails if arguments are passed when negated', () => {
|
|
108
|
-
expect(() => {
|
|
109
|
-
expect(() => {}).not.toErrorDev('not unexpected?');
|
|
110
|
-
}).to.throw(
|
|
111
|
-
'Expected no call to console.error but provided messages. ' +
|
|
112
|
-
"If you want to make sure a certain message isn't logged prefer the positive. " +
|
|
113
|
-
'By expecting certain messages you automatically expect that no other messages are logged',
|
|
114
|
-
);
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
it('ignores `false` messages', () => {
|
|
118
|
-
const isReact16 = false;
|
|
119
|
-
expect(() => {
|
|
120
|
-
expect(() => {}).toErrorDev([isReact16 && 'some legacy error message']);
|
|
121
|
-
}).not.to.throw();
|
|
122
|
-
});
|
|
123
|
-
});
|
|
124
|
-
});
|
package/src/initMatchers.ts
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import * as chai from 'chai';
|
|
2
|
-
import * as DomTestingLibrary from '@testing-library/dom';
|
|
3
|
-
import type { ElementHandle } from '@playwright/test';
|
|
4
|
-
|
|
5
|
-
// https://stackoverflow.com/a/46755166/3406963
|
|
6
|
-
declare global {
|
|
7
|
-
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
8
|
-
namespace Chai {
|
|
9
|
-
interface Assertion {
|
|
10
|
-
/**
|
|
11
|
-
* Checks if the element handle is actually focused i.e. the element handle is pointing to `document.activeElement`.
|
|
12
|
-
*/
|
|
13
|
-
toHaveFocus(): Promise<void>;
|
|
14
|
-
/**
|
|
15
|
-
* Checks if the element handle has the given attribute.
|
|
16
|
-
* @example expect($element).toHaveAttribute('aria-expanded') is like `[aria-expanded]` CSS selector
|
|
17
|
-
* @example expect($element).toHaveAttribute('aria-expanded', 'true') is like `[aria-expanded="true"]` CSS selector
|
|
18
|
-
*/
|
|
19
|
-
toHaveAttribute(attributeName: string, attributeValue?: string): Promise<void>;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
interface Window {
|
|
24
|
-
DomTestingLibrary: typeof DomTestingLibrary;
|
|
25
|
-
/**
|
|
26
|
-
* @example $element.evaluate(element => window.pageElementToString(element))
|
|
27
|
-
*/
|
|
28
|
-
elementToString(element: Node | null | undefined): string | false;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
chai.use((chaiAPI, utils) => {
|
|
33
|
-
chai.Assertion.addMethod('toHaveFocus', async function elementHandleIsFocused() {
|
|
34
|
-
const $elementOrHandle: ElementHandle | Promise<ElementHandle> = utils.flag(this, 'object');
|
|
35
|
-
if ($elementOrHandle == null) {
|
|
36
|
-
throw new chai.AssertionError(
|
|
37
|
-
`Expected an element handle but got ${String($elementOrHandle)}.`,
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
const $element =
|
|
41
|
-
typeof ($elementOrHandle as Promise<any>).then === 'function'
|
|
42
|
-
? await ($elementOrHandle as Promise<ElementHandle>)
|
|
43
|
-
: ($elementOrHandle as ElementHandle);
|
|
44
|
-
|
|
45
|
-
const { isFocused, stringifiedActiveElement, stringifiedElement } = await $element.evaluate(
|
|
46
|
-
(element) => {
|
|
47
|
-
const activeElement =
|
|
48
|
-
element.ownerDocument !== null ? element.ownerDocument.activeElement : null;
|
|
49
|
-
return {
|
|
50
|
-
isFocused: activeElement === element,
|
|
51
|
-
stringifiedElement: window.elementToString(element),
|
|
52
|
-
stringifiedActiveElement: window.elementToString(activeElement),
|
|
53
|
-
};
|
|
54
|
-
},
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
this.assert(
|
|
58
|
-
isFocused,
|
|
59
|
-
`expected element to have focus`,
|
|
60
|
-
`expected element to NOT have focus \n${stringifiedElement}`,
|
|
61
|
-
stringifiedElement,
|
|
62
|
-
stringifiedActiveElement,
|
|
63
|
-
);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
chai.Assertion.addMethod(
|
|
67
|
-
'toHaveAttribute',
|
|
68
|
-
async function elementHandleHasAttribute(attributeName: string, attributeValue?: string) {
|
|
69
|
-
const $elementOrHandle: ElementHandle | Promise<ElementHandle> = utils.flag(this, 'object');
|
|
70
|
-
if ($elementOrHandle == null) {
|
|
71
|
-
throw new chai.AssertionError(
|
|
72
|
-
`Expected an element handle but got ${String($elementOrHandle)}.`,
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
|
-
const $element =
|
|
76
|
-
typeof ($elementOrHandle as Promise<any>).then === 'function'
|
|
77
|
-
? await ($elementOrHandle as Promise<ElementHandle>)
|
|
78
|
-
: ($elementOrHandle as ElementHandle);
|
|
79
|
-
|
|
80
|
-
const actualAttributeValue = await $element.getAttribute(attributeName);
|
|
81
|
-
|
|
82
|
-
if (attributeValue === undefined) {
|
|
83
|
-
this.assert(
|
|
84
|
-
actualAttributeValue !== null,
|
|
85
|
-
`expected element to have attribute \`${attributeName}\``,
|
|
86
|
-
`expected element to NOT have attribute \`${attributeName}\``,
|
|
87
|
-
null,
|
|
88
|
-
null,
|
|
89
|
-
);
|
|
90
|
-
} else {
|
|
91
|
-
this.assert(
|
|
92
|
-
actualAttributeValue === attributeValue,
|
|
93
|
-
`expected element to have attribute \`${attributeName}="${attributeValue}"\``,
|
|
94
|
-
`expected element to NOT have attribute \`${attributeName}="${attributeValue}"\``,
|
|
95
|
-
attributeValue,
|
|
96
|
-
actualAttributeValue,
|
|
97
|
-
);
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
);
|
|
101
|
-
});
|
package/src/mochaHooks.js
DELETED
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
const formatUtil = require('format-util');
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @typedef {(this: import('mocha').Context) => void} MochaHook
|
|
6
|
-
*
|
|
7
|
-
* @typedef {object} MochaHooks
|
|
8
|
-
* @property {MochaHook[]} beforeAll
|
|
9
|
-
* @property {MochaHook[]} afterAll
|
|
10
|
-
* @property {MochaHook[]} beforeEach
|
|
11
|
-
* @property {MochaHook[]} afterEach
|
|
12
|
-
*
|
|
13
|
-
* @typedef {object} Mocha -- custom definition for `const mocha = require('mocha')`
|
|
14
|
-
* @property {import('mocha').utils} utils
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
const isKarma = Boolean(process.env.KARMA);
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Polyfills for https://github.com/facebook/react/issues/19416.
|
|
21
|
-
* @param {[stack: string, message: string][]} consoleCalls
|
|
22
|
-
* @returns {[stack: string, message: string][]}
|
|
23
|
-
*/
|
|
24
|
-
function dedupeActWarningsByComponent(consoleCalls) {
|
|
25
|
-
/**
|
|
26
|
-
* @type {[stack: string, message: string][]}
|
|
27
|
-
*/
|
|
28
|
-
const dedupedCalls = [];
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* @type {string | undefined}
|
|
32
|
-
*/
|
|
33
|
-
let updatingComponentOutsideAct;
|
|
34
|
-
|
|
35
|
-
consoleCalls.forEach(([stack, message]) => {
|
|
36
|
-
const componentName = message.match(
|
|
37
|
-
/An update to (.+?) ran an effect, but was not wrapped in act/,
|
|
38
|
-
)?.[1];
|
|
39
|
-
|
|
40
|
-
const duplicateMissingActWarning =
|
|
41
|
-
componentName !== undefined && componentName === updatingComponentOutsideAct;
|
|
42
|
-
if (!duplicateMissingActWarning) {
|
|
43
|
-
dedupedCalls.push([stack, message]);
|
|
44
|
-
}
|
|
45
|
-
updatingComponentOutsideAct = componentName;
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
return dedupedCalls;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* @param {Mocha} Mocha
|
|
53
|
-
* @param {'warn' | 'error'} methodName
|
|
54
|
-
* @param {string} expectedMatcher
|
|
55
|
-
* @returns MochaHooks
|
|
56
|
-
*/
|
|
57
|
-
function createUnexpectedConsoleMessagesHooks(Mocha, methodName, expectedMatcher) {
|
|
58
|
-
/**
|
|
59
|
-
* @type {MochaHooks}
|
|
60
|
-
*/
|
|
61
|
-
const mochaHooks = {
|
|
62
|
-
beforeAll: [],
|
|
63
|
-
afterAll: [],
|
|
64
|
-
beforeEach: [],
|
|
65
|
-
afterEach: [],
|
|
66
|
-
};
|
|
67
|
-
/**
|
|
68
|
-
* @type {[stack: string, message: string][]}
|
|
69
|
-
*/
|
|
70
|
-
const unexpectedCalls = [];
|
|
71
|
-
const stackTraceFilter = Mocha.utils.stackTraceFilter();
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* @param {string} format
|
|
75
|
-
* @param {...unknown} args
|
|
76
|
-
* @returns {void}
|
|
77
|
-
*/
|
|
78
|
-
function logUnexpectedConsoleCalls(format, ...args) {
|
|
79
|
-
const message = formatUtil(format, ...args);
|
|
80
|
-
|
|
81
|
-
// Safe stack so that test dev can track where the unexpected console message was created.
|
|
82
|
-
const { stack } = new Error();
|
|
83
|
-
if (stack === undefined) {
|
|
84
|
-
throw new TypeError(
|
|
85
|
-
`Unable to get stack. Logging unexpected console calls is only supported in environments where Error.prototype.stack is implemented.`,
|
|
86
|
-
);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (process.env.NODE_ENV === 'production') {
|
|
90
|
-
// TODO: mock scheduler
|
|
91
|
-
if (message.includes('act(...) is not supported in production builds of React')) {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
if (message.includes('Warning: useLayoutEffect does nothing on the server')) {
|
|
97
|
-
// Controversial warning that is commonly ignored by switching to `useEffect` on the server.
|
|
98
|
-
// https://github.com/facebook/react/issues/14927
|
|
99
|
-
// However, this switch doesn't work since it relies on environment sniffing and we test SSR in a browser environment.
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Unclear why this is an issue for the current occurrences of this warning.
|
|
104
|
-
// TODO: Revisit once https://github.com/facebook/react/issues/22796 is resolved
|
|
105
|
-
if (
|
|
106
|
-
message.includes(
|
|
107
|
-
'Detected multiple renderers concurrently rendering the same context provider.',
|
|
108
|
-
)
|
|
109
|
-
) {
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
unexpectedCalls.push([
|
|
114
|
-
// first line includes the (empty) error message
|
|
115
|
-
// i.e. Remove the `Error:` line
|
|
116
|
-
// second line is this frame
|
|
117
|
-
stackTraceFilter(stack.split('\n').slice(2).join('\n')),
|
|
118
|
-
message,
|
|
119
|
-
]);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* @type {Console['warn' | 'error']}
|
|
124
|
-
*/
|
|
125
|
-
let originalConsoleMethod;
|
|
126
|
-
mochaHooks.beforeAll.push(function registerConsoleStub() {
|
|
127
|
-
// eslint-disable-next-line no-console
|
|
128
|
-
originalConsoleMethod = console[methodName];
|
|
129
|
-
// eslint-disable-next-line no-console
|
|
130
|
-
console[methodName] = logUnexpectedConsoleCalls;
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
mochaHooks.afterAll.push(function registerConsoleStub() {
|
|
134
|
-
// eslint-disable-next-line no-console
|
|
135
|
-
console[methodName] = originalConsoleMethod;
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
mochaHooks.afterEach.push(function flushUnexpectedCalls() {
|
|
139
|
-
const actionableCalls = dedupeActWarningsByComponent(unexpectedCalls);
|
|
140
|
-
const actionableCallCount = actionableCalls.length;
|
|
141
|
-
const formattedCalls = actionableCalls.map(
|
|
142
|
-
([stack, message], index) =>
|
|
143
|
-
`console.${methodName} message #${index + 1}:\n ${message}\n\nStack:\n${stack}`,
|
|
144
|
-
);
|
|
145
|
-
unexpectedCalls.length = 0;
|
|
146
|
-
|
|
147
|
-
// eslint-disable-next-line no-console
|
|
148
|
-
if (console[methodName] !== logUnexpectedConsoleCalls) {
|
|
149
|
-
throw new Error(`Did not tear down spy or stub of console.${methodName} in your test.`);
|
|
150
|
-
}
|
|
151
|
-
if (actionableCallCount > 0) {
|
|
152
|
-
// In karma `file` is `null`.
|
|
153
|
-
// We still have the stacktrace though
|
|
154
|
-
// @ts-expect-error -- this.currentTest being undefined would be a bug
|
|
155
|
-
const location = this.currentTest.file ?? '(unknown file)';
|
|
156
|
-
const message =
|
|
157
|
-
`Expected test not to call console.${methodName}() but instead received ${actionableCallCount} calls.\n\n` +
|
|
158
|
-
'If the warning is expected, test for it explicitly by ' +
|
|
159
|
-
// Don't add any punctuation after the location.
|
|
160
|
-
// Otherwise it's not clickable in IDEs
|
|
161
|
-
`using the ${expectedMatcher}() matcher.\nTest location:\n ${location} `;
|
|
162
|
-
|
|
163
|
-
const error = new Error(`${message}\n\n${formattedCalls.join('\n\n')}`);
|
|
164
|
-
// The stack of `flushUnexpectedCalls` is irrelevant.
|
|
165
|
-
// It includes no clue where the test was triggered
|
|
166
|
-
error.stack = '';
|
|
167
|
-
|
|
168
|
-
if (isKarma) {
|
|
169
|
-
// @ts-expect-error -- this.currentTest being undefined would be a bug
|
|
170
|
-
const testPath = `"${this.currentTest.fullTitle()}"`;
|
|
171
|
-
|
|
172
|
-
error.message += `\n\nin ${testPath}`;
|
|
173
|
-
throw error;
|
|
174
|
-
} else {
|
|
175
|
-
// @ts-expect-error -- this.test being undefined would be a bug
|
|
176
|
-
this.test.error(error);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
return mochaHooks;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* @param {Mocha} Mocha
|
|
186
|
-
* @returns MochaHooks
|
|
187
|
-
*/
|
|
188
|
-
function createMochaHooks(Mocha) {
|
|
189
|
-
const warnHooks = createUnexpectedConsoleMessagesHooks(Mocha, 'warn', 'toWarnDev');
|
|
190
|
-
const errorHooks = createUnexpectedConsoleMessagesHooks(Mocha, 'error', 'toErrorDev');
|
|
191
|
-
|
|
192
|
-
return {
|
|
193
|
-
beforeAll: [...warnHooks.beforeAll, ...errorHooks.beforeAll],
|
|
194
|
-
afterAll: [...warnHooks.afterAll, ...errorHooks.afterAll],
|
|
195
|
-
beforeEach: [...warnHooks.beforeEach, ...errorHooks.beforeEach],
|
|
196
|
-
afterEach: [...warnHooks.afterEach, ...errorHooks.afterEach],
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
module.exports = { createMochaHooks };
|
package/src/mochaHooks.test.js
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import * as Mocha from 'mocha';
|
|
2
|
-
import { expect } from 'chai';
|
|
3
|
-
import * as React from 'react';
|
|
4
|
-
import { stub } from 'sinon';
|
|
5
|
-
import { createMochaHooks } from './mochaHooks';
|
|
6
|
-
import { createRenderer, act } from './createRenderer';
|
|
7
|
-
import describeSkipIf from './describeSkipIf';
|
|
8
|
-
|
|
9
|
-
describeSkipIf(process.env.VITEST)('mochaHooks', () => {
|
|
10
|
-
// one block per hook.
|
|
11
|
-
describe('afterEach', () => {
|
|
12
|
-
describe('on unexpected console.(warn|error) in afterEach', function suite() {
|
|
13
|
-
const mochaHooks = createMochaHooks(Mocha);
|
|
14
|
-
|
|
15
|
-
beforeEach(function beforeEachHook() {
|
|
16
|
-
mochaHooks.beforeAll.forEach((beforeAllMochaHook) => {
|
|
17
|
-
beforeAllMochaHook.call(this);
|
|
18
|
-
});
|
|
19
|
-
mochaHooks.beforeEach.forEach((beforeEachMochaHook) => {
|
|
20
|
-
beforeEachMochaHook.call(this);
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('throws an error', () => {
|
|
25
|
-
console.warn('unexpected warning');
|
|
26
|
-
console.error('unexpected error');
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
afterEach(function afterEachHook() {
|
|
30
|
-
const errorStub = stub(this.test, 'error');
|
|
31
|
-
mochaHooks.afterEach.forEach((afterEachMochaHook) => {
|
|
32
|
-
afterEachMochaHook.call(this);
|
|
33
|
-
});
|
|
34
|
-
mochaHooks.afterAll.forEach((afterAllMochaHook) => {
|
|
35
|
-
afterAllMochaHook.call(this);
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
expect(errorStub.callCount).to.equal(2);
|
|
39
|
-
expect(String(errorStub.firstCall.args[0])).to.include(
|
|
40
|
-
'console.warn message #1:\n unexpected warning\n\nStack:',
|
|
41
|
-
);
|
|
42
|
-
expect(String(errorStub.secondCall.args[0])).to.include(
|
|
43
|
-
'console.error message #1:\n unexpected error\n\nStack:',
|
|
44
|
-
);
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
// TODO: May not be relevant in React 18
|
|
49
|
-
describe('when having missing act() warnings by component', () => {
|
|
50
|
-
const mochaHooks = createMochaHooks(Mocha);
|
|
51
|
-
// missing act warnings only happen in StrictMode
|
|
52
|
-
const { render } = createRenderer({ strict: true });
|
|
53
|
-
|
|
54
|
-
beforeEach(function beforeEachHook() {
|
|
55
|
-
mochaHooks.beforeAll.forEach((beforeAllMochaHook) => {
|
|
56
|
-
beforeAllMochaHook.call(this);
|
|
57
|
-
});
|
|
58
|
-
mochaHooks.beforeEach.forEach((beforeEachMochaHook) => {
|
|
59
|
-
beforeEachMochaHook.call(this);
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('dedupes them', () => {
|
|
64
|
-
const Child = React.forwardRef(function Child() {
|
|
65
|
-
React.useEffect(() => {});
|
|
66
|
-
React.useEffect(() => {});
|
|
67
|
-
return null;
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
let unsafeSetState;
|
|
71
|
-
function Parent() {
|
|
72
|
-
const [state, setState] = React.useState(0);
|
|
73
|
-
// TODO: uncomment once we enable eslint-plugin-react-compiler // eslint-disable-next-line react-compiler/react-compiler -- unsafeSetState is required outside the component
|
|
74
|
-
unsafeSetState = setState;
|
|
75
|
-
|
|
76
|
-
React.useEffect(() => {});
|
|
77
|
-
React.useEffect(() => {});
|
|
78
|
-
|
|
79
|
-
return <Child rerender={state} />;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
render(<Parent />);
|
|
83
|
-
|
|
84
|
-
// not wrapped in act()
|
|
85
|
-
unsafeSetState(1);
|
|
86
|
-
// make sure effects are flushed
|
|
87
|
-
act(() => {});
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
afterEach(function afterEachHook() {
|
|
91
|
-
const errorStub = stub(this.test, 'error');
|
|
92
|
-
mochaHooks.afterEach.forEach((afterEachMochaHook) => {
|
|
93
|
-
afterEachMochaHook.call(this);
|
|
94
|
-
});
|
|
95
|
-
mochaHooks.afterAll.forEach((afterAllMochaHook) => {
|
|
96
|
-
afterAllMochaHook.call(this);
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
expect(errorStub.callCount).to.equal(1);
|
|
100
|
-
const error = String(errorStub.firstCall.args[0]);
|
|
101
|
-
expect(
|
|
102
|
-
error.match(/An update to Parent inside a test was not wrapped in act/g),
|
|
103
|
-
).to.have.lengthOf(1);
|
|
104
|
-
expect(
|
|
105
|
-
error.match(/An update to Parent ran an effect, but was not wrapped in act/g) ?? [],
|
|
106
|
-
).to.have.lengthOf(React.startTransition !== undefined ? 0 : 1);
|
|
107
|
-
expect(
|
|
108
|
-
error.match(
|
|
109
|
-
/An update to ForwardRef\(Child\) ran an effect, but was not wrapped in act/g,
|
|
110
|
-
) ?? [],
|
|
111
|
-
).to.have.lengthOf(React.startTransition !== undefined ? 0 : 1);
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
});
|
package/src/reactMajor.ts
DELETED
package/src/setupBabel.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
// In playwright we sometimes write functions that are executed in the browser environment.
|
|
2
|
-
// Since we can't tell babel which parts of the code are executed in which environment we can only disable it entirely.
|
|
3
|
-
// We're only stripping types and compiling ES6 to CommonJS modules which should be safe.
|
|
4
|
-
|
|
5
|
-
require('@babel/register')({
|
|
6
|
-
configFile: false,
|
|
7
|
-
extensions: ['.js', '.ts', '.tsx'],
|
|
8
|
-
presets: [require.resolve('@babel/preset-typescript')],
|
|
9
|
-
plugins: [
|
|
10
|
-
require.resolve('@babel/plugin-transform-modules-commonjs'),
|
|
11
|
-
require.resolve('babel-plugin-transform-import-meta'),
|
|
12
|
-
],
|
|
13
|
-
});
|
package/src/setupJSDOM.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
const testingLibrary = require('@testing-library/dom');
|
|
2
|
-
const Mocha = require('mocha');
|
|
3
|
-
const createDOM = require('./createDOM');
|
|
4
|
-
const { createMochaHooks } = require('./mochaHooks');
|
|
5
|
-
|
|
6
|
-
// Enable missing act warnings: https://github.com/reactwg/react-18/discussions/102
|
|
7
|
-
globalThis.jest = null;
|
|
8
|
-
globalThis.IS_REACT_ACT_ENVIRONMENT = true;
|
|
9
|
-
|
|
10
|
-
createDOM();
|
|
11
|
-
require('./init');
|
|
12
|
-
|
|
13
|
-
testingLibrary.configure({
|
|
14
|
-
// JSDOM logs errors otherwise on `getComputedStyle(element, pseudoElement)` calls.
|
|
15
|
-
computedStyleSupportsPseudoElements: false,
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
const mochaHooks = createMochaHooks(Mocha);
|
|
19
|
-
|
|
20
|
-
module.exports = { mochaHooks };
|