| Feb | MAR | Apr |
| 01 | ||
| 2020 | 2021 | 2022 |
COLLECTED BY
Formed in 2009, the Archive Team (not to be confused with the archive.org Archive-It Team) is a rogue archivist collective dedicated to saving copies of rapidly dying or deleted websites for the sake of history and digital heritage. The group is 100% composed of volunteers and interested parties, and has expanded into a large amount of related projects for saving online and digital history.
History is littered with hundreds of conflicts over the future of a community, group, location or business that were "resolved" when one of the parties stepped ahead and destroyed what was there. With the original point of contention destroyed, the debates would fall to the wayside. Archive Team believes that by duplicated condemned data, the conversation and debate can continue, as well as the richness and insight gained by keeping the materials. Our projects have ranged in size from a single volunteer downloading the data to a small-but-critical site, to over 100 volunteers stepping forward to acquire terabytes of user-created data to save for future generations.
The main site for Archive Team is at archiveteam.org and contains up to the date information on various projects, manifestos, plans and walkthroughs.
This collection contains the output of many Archive Team projects, both ongoing and completed. Thanks to the generous providing of disk space by the Internet Archive, multi-terabyte datasets can be made available, as well as in use by the Wayback Machine, providing a path back to lost websites and work.
Our collection has grown to the point of having sub-collections for the type of data we acquire. If you are seeking to browse the contents of these collections, the Wayback Machine is the best first stop. Otherwise, you are free to dig into the stacks to see what you may find.
The Archive Team Panic Downloads are full pulldowns of currently extant websites, meant to serve as emergency backups for needed sites that are in danger of closing, or which will be missed dearly if suddenly lost due to hard drive crashes or server failures.
Collection: Archive Team: URLs
module.exports = { setupFilesAfterEnv: ['./rtl.setup.js']};module.exports = {
setupFilesAfterEnv: ['./rtl.setup.js']
};
rtl.setup.js
// See https://github.com/kentcdodds/react-testing-library#global-configimport 'jest-dom/extend-expect';import 'react-testing-library/cleanup-after-each';// See https://github.com/kentcdodds/react-testing-library#global-config
import 'jest-dom/extend-expect';
import 'react-testing-library/cleanup-after-each';
it('renders personalized greeting', async () => { // Render new instance in every test to prevent leaking state const { getByText } = render(<HelloMessage name="Satoshi" />); await waitForElement(() => getByText(/hello Satoshi/i));});it('renders personalized greeting', async () => {
// Render new instance in every test to prevent leaking state
const { getByText } = render(<HelloMessage name="Satoshi" />);
await waitForElement(() => getByText(/hello Satoshi/i));
});
it('calls "onClick" prop on button click', () => { // Render new instance in every test to prevent leaking state const onClick = jest.fn(); const { getByText } = render(<Button onClick={onClick} />); fireEvent.click(getByText(/click me nao/i)); expect(onClick).toHaveBeenCalled();});it('calls "onClick" prop on button click', () => {
// Render new instance in every test to prevent leaking state
const onClick = jest.fn();
const { getByText } = render(<Button onClick={onClick} />);
fireEvent.click(getByText(/click me nao/i));
expect(onClick).toHaveBeenCalled();
});
@react-mock/state to mock the component state.
test.js
render(
// Hoist helper functions (but not vars) to reuse between test casesconst renderComponent = ({ count }) => render( <StateMock state={{ count }}> <StatefulCounter /> </StateMock> );it('renders initial count', async () => { // Render new instance in every test to prevent leaking state const { getByText } = renderComponent({ count: 5 }); await waitForElement(() => getByText(/clicked 5 times/i));});it('increments count', async () => { // Render new instance in every test to prevent leaking state const { getByText } = renderComponent({ count: 5 }); fireEvent.click(getByText('+1')); await waitForElement(() => getByText(/clicked 6 times/i));});// Hoist helper functions (but not vars) to reuse between test cases
const renderComponent = ({ count }) =>
render(
<StateMock state={{ count }}>
<StatefulCounter />
</StateMock>
);
it('renders initial count', async () => {
// Render new instance in every test to prevent leaking state
const { getByText } = renderComponent({ count: 5 });
await waitForElement(() => getByText(/clicked 5 times/i));
});
it('increments count', async () => {
// Render new instance in every test to prevent leaking state
const { getByText } = renderComponent({ count: 5 });
fireEvent.click(getByText('+1'));
await waitForElement(() => getByText(/clicked 6 times/i));
});
// Hoist helper functions (but not vars) to reuse between test casesconst renderComponent = ({ count }) => render( <Provider store={createStore(counterReducer, { count })}> <ReduxCounter /> </Provider> );it('renders initial count', async () => { // Render new instance in every test to prevent leaking state const { getByText } = renderComponent({ count: 5 }); await waitForElement(() => getByText(/clicked 5 times/i));});it('increments count', async () => { // Render new instance in every test to prevent leaking state const { getByText } = renderComponent({ count: 5 }); fireEvent.click(getByText('+1')); await waitForElement(() => getByText(/clicked 6 times/i));});// Hoist helper functions (but not vars) to reuse between test cases
const renderComponent = ({ count }) =>
render(
<Provider store={createStore(counterReducer, { count })}>
<ReduxCounter />
</Provider>
);
it('renders initial count', async () => {
// Render new instance in every test to prevent leaking state
const { getByText } = renderComponent({ count: 5 });
await waitForElement(() => getByText(/clicked 5 times/i));
});
it('increments count', async () => {
// Render new instance in every test to prevent leaking state
const { getByText } = renderComponent({ count: 5 });
fireEvent.click(getByText('+1'));
await waitForElement(() => getByText(/clicked 6 times/i));
});
Link to another location.
First we make sure the component renders a param from the initial URL. Then we check that the URL param from a new location is rendered upon clicking on the Link element, which proves that the page has successfully routed.
Alternatively, we could just test the toprop of the Link element. That's also fine. But this test is closer to how a user thinks: Click on a link. Did the linked page open?
This type of thinking makes tests more resilient against implementation changes, like upgrading the router library to a new API.
test.js
render(
// Hoist helper functions (but not vars) to reuse between test casesconst renderComponent = ({ userId }) => render( <MemoryRouter initialEntries={[`/users/${userId}`]}> <Route path="/users/:userId"> <UserWithRouter /> </Route> </MemoryRouter> );it('renders initial user id', async () => { // Render new instance in every test to prevent leaking state const { getByText } = renderComponent({ userId: 5 }); await waitForElement(() => getByText(/user #5/i));});it('renders next user id', async () => { // Render new instance in every test to prevent leaking state const { getByText } = renderComponent({ userId: 5 }); fireEvent.click(getByText(/next user/i)); await waitForElement(() => getByText(/user #6/i));});// Hoist helper functions (but not vars) to reuse between test cases
const renderComponent = ({ userId }) =>
render(
<MemoryRouter initialEntries={[`/users/${userId}`]}>
<Route path="/users/:userId">
<UserWithRouter />
</Route>
</MemoryRouter>
);
it('renders initial user id', async () => {
// Render new instance in every test to prevent leaking state
const { getByText } = renderComponent({ userId: 5 });
await waitForElement(() => getByText(/user #5/i));
});
it('renders next user id', async () => {
// Render new instance in every test to prevent leaking state
const { getByText } = renderComponent({ userId: 5 });
fireEvent.click(getByText(/next user/i));
await waitForElement(() => getByText(/user #6/i));
});
@react-mock/fetch to mock the server requests.
test.js
render(
// Hoist helper functions (but not vars) to reuse between test casesconst renderComponent = ({ count }) => render( <FetchMock mocks={[ { matcher: '/count', method: 'GET', response: { count } }, { matcher: '/count', method: 'POST', response: { count: count + 1 } } ]} > <ServerCounter /> </FetchMock> );it('renders initial count', async () => { // Render new instance in every test to prevent leaking state const { getByText } = renderComponent({ count: 5 }); // It takes time for the counter to appear because // the GET request has a slight delay await waitForElement(() => getByText(/clicked 5 times/i));});it('increments count', async () => { // Render new instance in every test to prevent leaking state const { getByText } = renderComponent({ count: 5 }); // It takes time for the button to appear because // the GET request has a slight delay await waitForElement(() => getByText('+1')); fireEvent.click(getByText('+1')); // The counter doesn't update immediately because // the POST request is asynchronous await waitForElement(() => getByText(/clicked 6 times/i));});// Hoist helper functions (but not vars) to reuse between test cases
const renderComponent = ({ count }) =>
render(
<FetchMock
mocks={[
{ matcher: '/count', method: 'GET', response: { count } },
{ matcher: '/count', method: 'POST', response: { count: count + 1 } }
]}
>
<ServerCounter />
</FetchMock>
);
it('renders initial count', async () => {
// Render new instance in every test to prevent leaking state
const { getByText } = renderComponent({ count: 5 });
// It takes time for the counter to appear because
// the GET request has a slight delay
await waitForElement(() => getByText(/clicked 5 times/i));
});
it('increments count', async () => {
// Render new instance in every test to prevent leaking state
const { getByText } = renderComponent({ count: 5 });
// It takes time for the button to appear because
// the GET request has a slight delay
await waitForElement(() => getByText('+1'));
fireEvent.click(getByText('+1'));
// The counter doesn't update immediately because
// the POST request is asynchronous
await waitForElement(() => getByText(/clicked 6 times/i));
});
@react-mock/xhr to mock the server requests.
test.js
async (req, res) => res.status(200).body({ count });
const postRes = count => (req, res) =>
res.status(200).body({ count: count + 1 });
const renderComponent = ({ count }) =>
render(
// Hoist helper functions (but not vars) to reuse between test casesconst getRes = count => async (req, res) => res.status(200).body({ count });const postRes = count => (req, res) => res.status(200).body({ count: count + 1 });const renderComponent = ({ count }) => render( <XhrMock mocks={[ { url: '/count', method: 'GET', response: getRes(count) }, { url: '/count', method: 'POST', response: postRes(count) } ]} > <ServerCounter /> </XhrMock> );it('renders initial count', async () => { // Render new instance in every test to prevent leaking state const { getByText } = renderComponent({ count: 5 }); // It takes time for the counter to appear because // the GET request has a slight delay await waitForElement(() => getByText(/clicked 5 times/i));});it('increments count', async () => { // Render new instance in every test to prevent leaking state const { getByText } = renderComponent({ count: 5 }); // It takes time for the button to appear because // the GET request has a slight delay await waitForElement(() => getByText('+1')); fireEvent.click(getByText('+1')); // The counter doesn't update immediately because // the POST request is asynchronous await waitForElement(() => getByText(/clicked 6 times/i));});// Hoist helper functions (but not vars) to reuse between test cases
const getRes = count => async (req, res) => res.status(200).body({ count });
const postRes = count => (req, res) =>
res.status(200).body({ count: count + 1 });
const renderComponent = ({ count }) =>
render(
<XhrMock
mocks={[
{ url: '/count', method: 'GET', response: getRes(count) },
{ url: '/count', method: 'POST', response: postRes(count) }
]}
>
<ServerCounter />
</XhrMock>
);
it('renders initial count', async () => {
// Render new instance in every test to prevent leaking state
const { getByText } = renderComponent({ count: 5 });
// It takes time for the counter to appear because
// the GET request has a slight delay
await waitForElement(() => getByText(/clicked 5 times/i));
});
it('increments count', async () => {
// Render new instance in every test to prevent leaking state
const { getByText } = renderComponent({ count: 5 });
// It takes time for the button to appear because
// the GET request has a slight delay
await waitForElement(() => getByText('+1'));
fireEvent.click(getByText('+1'));
// The counter doesn't update immediately because
// the POST request is asynchronous
await waitForElement(() => getByText(/clicked 6 times/i));
});
@react-mock/localstorage to mock the cached data.
test.js
render(
// Hoist helper functions (but not vars) to reuse between test casesconst renderComponent = ({ name }) => render( <LocalStorageMock items={{ name }}> <PersistentForm /> </LocalStorageMock> );const submitForm = ({ getByText, getByLabelText }, { name }) => { fireEvent.change(getByLabelText('Name'), { target: { value: name } }); fireEvent.click(getByText(/change name/i));};it('renders cached name', async () => { // Render new instance in every test to prevent leaking state const { getByText } = renderComponent({ name: 'Trent' }); await waitForElement(() => getByText(/welcome, Trent/i));});describe('on update', () => { it('renders updated name', async () => { // Render new instance in every test to prevent leaking state const utils = renderComponent({ name: 'Trent' }); submitForm(utils, { name: 'Trevor' }); await waitForElement(() => utils.getByText(/welcome, Trevor/i)); }); it('updates LocalStorage cache', () => { // Render new instance in every test to prevent leaking state const utils = renderComponent({ name: 'Trent' }); submitForm(utils, { name: 'Trevor' }); expect(localStorage.getItem('name')).toBe('Trevor'); });});// Hoist helper functions (but not vars) to reuse between test cases
const renderComponent = ({ name }) =>
render(
<LocalStorageMock items={{ name }}>
<PersistentForm />
</LocalStorageMock>
);
const submitForm = ({ getByText, getByLabelText }, { name }) => {
fireEvent.change(getByLabelText('Name'), { target: { value: name } });
fireEvent.click(getByText(/change name/i));
};
it('renders cached name', async () => {
// Render new instance in every test to prevent leaking state
const { getByText } = renderComponent({ name: 'Trent' });
await waitForElement(() => getByText(/welcome, Trent/i));
});
describe('on update', () => {
it('renders updated name', async () => {
// Render new instance in every test to prevent leaking state
const utils = renderComponent({ name: 'Trent' });
submitForm(utils, { name: 'Trevor' });
await waitForElement(() => utils.getByText(/welcome, Trevor/i));
});
it('updates LocalStorage cache', () => {
// Render new instance in every test to prevent leaking state
const utils = renderComponent({ name: 'Trent' });
submitForm(utils, { name: 'Trevor' });
expect(localStorage.getItem('name')).toBe('Trevor');
});
});
ThemeProvider context.
We're not testing style output here. The purpose of this test is merely to illustrate how to use ThemeProvider in tests.
test.js
render(
// Hoist helper functions (but not vars) to reuse between test casesconst renderComponent = ({ theme, name }) => render( <ThemeProvider theme={theme}> <HelloMessageStyled name={name} /> </ThemeProvider> );it('renders greeting', async () => { // Render new instance in every test to prevent leaking state const { getByText } = renderComponent({ theme: themeLight, name: 'Maggie' }); await waitForElement(() => getByText(/hello Maggie/i));});// Hoist helper functions (but not vars) to reuse between test cases
const renderComponent = ({ theme, name }) =>
render(
<ThemeProvider theme={theme}>
<HelloMessageStyled name={name} />
</ThemeProvider>
);
it('renders greeting', async () => {
// Render new instance in every test to prevent leaking state
const { getByText } = renderComponent({ theme: themeLight, name: 'Maggie' });
await waitForElement(() => getByText(/hello Maggie/i));
});
Tests powered by Jest react-mock Enzyme react-testing-library and @bigtest/interactor. Website powered by Babel Cosmos MDX Next.js Prism styled-components webpack and many more.
Finally, React makes it all possible!
Made with love by Ovidiu