Skip to content

Commit

Permalink
Create DOM fixture that tests state preservation of timed out content
Browse files Browse the repository at this point in the history
  • Loading branch information
acdlite committed Oct 15, 2018
1 parent 46386e2 commit add3f57
Show file tree
Hide file tree
Showing 2 changed files with 248 additions and 0 deletions.
1 change: 1 addition & 0 deletions fixtures/dom/src/components/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class Header extends React.Component {
<option value="/pointer-events">Pointer Events</option>
<option value="/mouse-events">Mouse Events</option>
<option value="/selection-events">Selection Events</option>
<option value="/suspense">Suspense</option>
</select>
</label>
<label htmlFor="react_version">
Expand Down
247 changes: 247 additions & 0 deletions fixtures/dom/src/components/fixtures/suspense/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
import Fixture from '../../Fixture';
import FixtureSet from '../../FixtureSet';
import TestCase from '../../TestCase';
import InputTestCase from './InputTestCase';
import ReplaceEmailInput from './ReplaceEmailInput';

const React = window.React;
const ReactDOM = window.ReactDOM;

const Suspense = React.unstable_Suspense;

let cache = new Set();

function AsyncStep({text, ms}) {
if (!cache.has(text)) {
throw new Promise(resolve =>
setTimeout(() => {
cache.add(text);
resolve();
}, ms)
);
}
return null;
}

let suspendyTreeIdCounter = 0;
class SuspendyTree extends React.Component {
id = suspendyTreeIdCounter++;
state = {
step: 1,
isHidden: false,
};
increment = () => this.setState(s => ({step: s.step + 1}));

componentDidMount() {
document.addEventListener('keydown', this.onKeydown);
}

componentWillUnmount() {
document.removeEventListener('keydown', this.onKeydown);
}

onKeydown = event => {
if (event.metaKey && event.key === 'Enter') {
this.increment();
}
};

render() {
return (
<React.Fragment>
<Suspense fallback={<div>"Loading..."</div>}>
<div>
<AsyncStep text={`${this.state.step} + ${this.id}`} ms={500} />
{this.props.children}
</div>
</Suspense>
<button onClick={this.increment}>Go</button>
</React.Fragment>
);
}
}

class TextInputFixtures extends React.Component {
render() {
return (
<FixtureSet
title="Suspense"
description="Preserving the state of timed-out children">
<div className="footnote">
Clicking "Go" will cause the fixtures to time-out for 1 second, then
restore. You can also use Command + Enter (or Control + Enter on
Windows, Linux), which is useful for preserving focus.
</div>
<TestCase title="Text selection where entire range times out">
<TestCase.Steps>
<li>Use your cursor to select the text below.</li>
<li>Click "Go".</li>
</TestCase.Steps>

<TestCase.ExpectedResult>
The text selection should not be lost.
</TestCase.ExpectedResult>

<Fixture>
<SuspendyTree>
Select this entire sentence (and only this sentence).
</SuspendyTree>
</Fixture>
</TestCase>
<TestCase title="Text selection that extends outside timed-out subtree">
<TestCase.Steps>
<li>
Use your cursor to select a range that includes both the text and
the "Go" button.
</li>
<li>Click "Go".</li>
</TestCase.Steps>

<TestCase.ExpectedResult>
The text selection should not be lost.
</TestCase.ExpectedResult>

<Fixture>
<SuspendyTree>
Select a range that includes both this sentence and the "Go"
button.
</SuspendyTree>
</Fixture>
</TestCase>
<TestCase title="Focus">
<TestCase.Steps>
<li>
Use your cursor to select a range that includes both the text and
the "Go" button.
</li>
<li>
Intead of clicking "Go", which switches focus, press Command +
Enter (or Control + Enter on Windows, Linux).
</li>
</TestCase.Steps>

<TestCase.ExpectedResult>
The ideal behavior is that the focus would not be lost, but
currently it is.
</TestCase.ExpectedResult>

<Fixture>
<SuspendyTree>
<button>Focus me</button>
</SuspendyTree>
</Fixture>
</TestCase>

<TestCase title="Uncontrolled form input">
<TestCase.Steps>
<li>Type something ("Hello") into the text input.</li>
<li>Click "Go".</li>
</TestCase.Steps>

<TestCase.ExpectedResult>
The text field's contents should not reset.
</TestCase.ExpectedResult>

<Fixture>
<SuspendyTree>
<input type="text" />
</SuspendyTree>
</Fixture>
</TestCase>

<TestCase title="Image flicker">
<TestCase.Steps>
<li>Click "Go".</li>
</TestCase.Steps>

<TestCase.ExpectedResult>
The image should reappear without flickering. The text should not
reflow.
</TestCase.ExpectedResult>

<Fixture>
<SuspendyTree>
<img src="https://upload.wikimedia.org/wikipedia/commons/e/ee/Atom_%282%29.png" />React
is cool
</SuspendyTree>
</Fixture>
</TestCase>

<TestCase title="Iframe">
<TestCase.Steps>
<li>
The iframe shows a nested version of this fixtures app. Navigate
to the "Text inputs" page.
</li>
<li>Select one of the checkboxes.</li>
<li>Click "Go".</li>
</TestCase.Steps>

<TestCase.ExpectedResult>
The iframe should still be on the "Text inputs" page. The checkbox
should still be checked. (Unfortunately, scroll position is lost.)
</TestCase.ExpectedResult>

<Fixture>
<SuspendyTree>
<iframe width="500" height="300" src="/" />
</SuspendyTree>
</Fixture>
</TestCase>

<TestCase title="Video playback">
<TestCase.Steps>
<li>Start playing the video, or seek to a specific position.</li>
<li>Click "Go".</li>
</TestCase.Steps>

<TestCase.ExpectedResult>
The playback position should stay the same.
</TestCase.ExpectedResult>

<Fixture>
<SuspendyTree>
<video controls>
<source
src="http://techslides.com/demos/sample-videos/small.webm"
type="video/webm"
/>
<source
src="http://techslides.com/demos/sample-videos/small.ogv"
type="video/ogg"
/>
<source
src="http://techslides.com/demos/sample-videos/small.mp4"
type="video/mp4"
/>
<source
src="http://techslides.com/demos/sample-videos/small.3gp"
type="video/3gp"
/>
</video>
</SuspendyTree>
</Fixture>
</TestCase>
<TestCase title="Audio playback">
<TestCase.Steps>
<li>Start playing the audio, or seek to a specific position.</li>
<li>Click "Go".</li>
</TestCase.Steps>

<TestCase.ExpectedResult>
The playback position should stay the same.
</TestCase.ExpectedResult>
<Fixture>
<SuspendyTree>
<audio controls={true}>
<source src="https://upload.wikimedia.org/wikipedia/commons/e/ec/Mozart_K448.ogg" />
</audio>
</SuspendyTree>
</Fixture>
</TestCase>
</FixtureSet>
);
}
}

export default TextInputFixtures;

0 comments on commit add3f57

Please sign in to comment.