Place any details about your implementation and usage of your app here.
Sauce Labs offers a variety of real devices in the cloud. Users can request available devices to remotely run their tests on them.
The goal of this challenge is to build a simple UI that displays some details about the devices and shows which of them are currently available.
Please make sure to fulfill the Acceptance Criteria when implementing the User Stories listed below.
We are looking forward to your submission. :)
48 hours. We know you have other duties. We want you to have enough time to comfortably complete this challenge.
Feel free to contact us.
- Create a good user experience. We want to provide our users with interfaces which are simple, useable and good-looking. Please do not use style libraries. Be creative. Add your own styling.
- Write your own components. We prepared this scaffold for you. We believe it comes with everything necessary to complete the tasks. You can use other libaries than the pre-installed ones for API requests, data handling etc., but do not use ready-made components. We included a few scripts and utilities as documented below under Available Scripts and Available Utilities. We suggest to follow the Ducks file structure.
- Write tests. All components and containers should be covered by unit tests. You may use the pre-installed libraries Chai, Enzyme and Sinon, but feel free to choose what fits your needs.
Please implement the following user stories based on the acceptance criteria described in the section above.
Mock endpoints to retrieve data for two different data centers:
http://localhost:3004/eu-devices
http://localhost:3004/us-devices
An image for each device can be found at:
https://d3ty40hendov17.cloudfront.net/device-pictures/{descriptorId}.png
Allow the user to choose between all operating systems, only Android and only iOS.
Periodically refresh the status of the displayed devices.
Mock endpoints to retrieve data for the two data centers:
http://localhost:3004/eu-availability
http://localhost:3004/us-availability
Display an animated indicator.
In the project directory, you can run the following commands.
Installs dependencies.
Runs the app in the development mode.
Open http://localhost:3000 to view it in the browser.
The page will reload if you make edits.
You will also see any lint errors in the console.
Starts the mock server.
Launches the test runner in the interactive watch mode.
See the documentation about running tests for more information.
You may use the following utilites to avoid writing boilerplate code.
import { createConstants } from '../utils/constant';
// Without the utility
export const NAMESPACE = 'manual';
export const STACKTAB_TOGGLE = `${NAMESPACE}/STACKTAB_TOGGLE`;
export const STACKTAB_OPEN = `${NAMESPACE}/STACKTAB_OPEN`;
export const STACKTAB_CLOSE = `${NAMESPACE}/STACKTAB_CLOSE`;
// Usage of the utility
export const NAMESPACE = 'manual';
export const STACKTAB = createConstants(NAMESPACE, 'stacktab')(
'TOGGLE',
'OPEN',
'CLOSE',
);
// This will generate:
// {
// TOGGLE: 'manual/STACKTAB_TOGGLE',
// OPEN: 'manual/STACKTAB_OPEN',
// CLOSE: 'manual/STACKTAB_CLOSE',
// }
import { createApiConstants } from '../utils/constant';
// Without the utility
export const NAMESPACE = 'manual';
export const SESSION_GET_REQUEST = `${NAMESPACE}/SESSION_GET_REQUEST`;
export const SESSION_GET_SUCCESS = `${NAMESPACE}/SESSION_GET_SUCCESS`;
export const SESSION_GET_FAILURE = `${NAMESPACE}/SESSION_GET_FAILURE`;
// Usage of the utility
export const NAMESPACE = 'manual';
export const SESSION_GET = createApiConstants(NAMESPACE, 'session_get');
// This will generate:
// {
// REQUEST: 'manual/SESSION_GET_REQUEST',
// SUCCESS: 'manual/SESSION_GET_SUCCESS',
// FAILURE: 'manual/SESSION_GET_FAILURE',
// }
For more info regarding action structure check flux standard action.
import { createAction } from '../utils/action';
// Without the utility
const openStacktab = (payload) => ({
type: constants.STACKTAB_OPEN,
payload,
});
// Usage of the utility
const openStacktab = createAction(constants.STACKTAB_OPEN);
import { createErrorAction } from '../utils/action';
// Without the utility
const removeSessionFailure = (payload) => ({
type: constants.SESSION_REMOVE_FAILURE,
payload,
error: true,
});
// Usage of the utility
const removeSessionFailure = createErrorAction(constants.SESSION_REMOVE_FAILURE);
This utility helps only with super simple api calls
import { createApiAction } from '../utils/action';
import { createApiConstants } from '../utils/constant';
// Without the utility
const getSessionRequest = () => ({
type: constants.SESSION_GET_REQUEST,
});
const getSessionSuccess = (payload, record) => ({
type: constants.SESSION_GET_SUCCESS,
payload,
record,
});
const getSessionFailure = (payload, record) => ({
type: constants.SESSION_GET_FAILURE,
payload,
record,
});
const getSession = (payload) => (dispatch) => {
dispatch(getSessionRequest());
return api.getSession(payload).then(
({ data }) => dispatch(getSessionSuccess(data)),
(error) => {
dispatch(getSessionFailure(error));
throw error;
},
);
};
// Usage of the utility
const constants = createApiConstants('session_get', 'manual') // <- this should be imported from constants file
const getSession = createApiAction(constants, (payload) => api.getSession(payload));
This project was bootstrapped with Create React App.