diff --git a/.babelrc b/.babelrc
new file mode 100644
index 0000000..7a016cf
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,3 @@
+{
+ "plugins": ["istanbul"]
+}
diff --git a/.env_example b/.env_example
index a7c7090..f608ab7 100644
--- a/.env_example
+++ b/.env_example
@@ -1,2 +1,4 @@
VITE_API_KEY=your_api_key_here
VITE_BASE_URL=https://api.unsplash.com
+VITEST=false
+SERVER_PORT=3033
diff --git a/.gitignore b/.gitignore
index 82d7fc6..d6e2d50 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,3 +25,10 @@ dist-ssr
*.njsprojc
*.sln
*.sw?
+
+# Local Netlify folder
+.netlify
+
+.nyc_output
+
+instrumented
diff --git a/.nycrc.json b/.nycrc.json
new file mode 100644
index 0000000..8601b9a
--- /dev/null
+++ b/.nycrc.json
@@ -0,0 +1,17 @@
+{
+ "all": true,
+ "extends": "@istanbuljs/nyc-config-typescript",
+ "check-coverage": true,
+ "include": ["src/**/*.ts", "src/**/*.tsx"],
+ "exclude": [
+ "cypress/**/*.*",
+ "**/*.d.ts",
+ "**/*.cy.tsx",
+ "**/*.cy.ts",
+ "**/*.test.tsx",
+ "**/*.test.ts",
+ "**/setup.ts",
+ "src/data/**/*.*",
+ "src/mocks/**/*.*"
+ ]
+}
diff --git a/cypress.config.ts b/cypress.config.ts
new file mode 100644
index 0000000..9a92e01
--- /dev/null
+++ b/cypress.config.ts
@@ -0,0 +1,19 @@
+import { defineConfig } from 'cypress';
+import cyCoverageTask from '@cypress/code-coverage/task';
+
+export default defineConfig({
+ env: {
+ codeCoverage: {
+ exclude: 'cypress/**/*.*',
+ instrumentation: false,
+ },
+ },
+ e2e: {
+ baseUrl: 'http://localhost:3001',
+ setupNodeEvents(on, config) {
+ cyCoverageTask(on, config);
+ return config;
+ },
+ video: false,
+ },
+});
diff --git a/cypress/e2e/spec.cy.ts b/cypress/e2e/spec.cy.ts
new file mode 100644
index 0000000..ad88745
--- /dev/null
+++ b/cypress/e2e/spec.cy.ts
@@ -0,0 +1,59 @@
+describe('RS React app E2E', () => {
+ it('should have About page', () => {
+ cy.visit('/about');
+
+ cy.get('h1')
+ .contains(/About us/i)
+ .should('be.visible');
+ });
+
+ it('should have Forms page', () => {
+ cy.visit('/forms');
+
+ cy.get('#userName').should('have.value', '');
+ cy.get('#userSurname').should('have.value', '');
+ cy.get('#userSurname').should('have.value', '');
+ cy.get('#userBirthday').should('have.value', '');
+ cy.get('button').should('have.text', 'Submit');
+ cy.get('button').contains('Submit').click();
+ cy.get('p.text-red-500').should('have.length', 7);
+
+ cy.get('#userName').type('Name').should('have.value', 'Name');
+ cy.get('#userSurname').type('Surame').should('have.value', 'Surame');
+
+ cy.get('#userGender-male').click().should('have.checked');
+ cy.get('#userGender-female').click().should('have.checked');
+ cy.get('#userTerms').click().should('have.checked');
+ cy.get('#userPromotions').click().should('have.checked');
+ });
+
+ it('should have 404 page', () => {
+ cy.visit('/notfound');
+
+ cy.get('h1')
+ .contains(/NotFound/i)
+ .should('be.visible');
+ });
+
+ it('should have home page with initial images', () => {
+ cy.visit('/');
+
+ cy.get('#search').should('have.value', '');
+
+ cy.get('img').should('have.length', 10);
+
+ cy.get('div > img').first().click();
+ });
+
+ it('should have home page with no images after applying unhandled search string', () => {
+ cy.visit('/');
+ cy.get('input').type('qwertyuiopijn').should('have.value', 'qwertyuiopijn');
+
+ cy.get('button').click();
+
+ cy.get('img').should('have.length', 0);
+ cy.get('h2')
+ .contains(/No Data to display/i)
+ .should('be.visible');
+ });
+});
diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json
new file mode 100644
index 0000000..02e4254
--- /dev/null
+++ b/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
diff --git a/cypress/plugins/index.ts b/cypress/plugins/index.ts
new file mode 100644
index 0000000..ba47f8b
--- /dev/null
+++ b/cypress/plugins/index.ts
@@ -0,0 +1,6 @@
+import istanbul from '@cypress/code-coverage/task';
+
+module.exports = (on, config) => {
+ on('task', istanbul);
+ return config;
+};
diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts
new file mode 100644
index 0000000..95857ae
--- /dev/null
+++ b/cypress/support/commands.ts
@@ -0,0 +1,37 @@
+///
+// ***********************************************
+// This example commands.ts shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+//
+// declare global {
+// namespace Cypress {
+// interface Chainable {
+// login(email: string, password: string): Chainable
+// drag(subject: string, options?: Partial): Chainable
+// dismiss(subject: string, options?: Partial): Chainable
+// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
+// }
+// }
+// }
diff --git a/cypress/support/component.ts b/cypress/support/component.ts
new file mode 100644
index 0000000..f568da8
--- /dev/null
+++ b/cypress/support/component.ts
@@ -0,0 +1 @@
+import '@cypress/code-coverage/support';
diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts
new file mode 100644
index 0000000..9d5979f
--- /dev/null
+++ b/cypress/support/e2e.ts
@@ -0,0 +1,21 @@
+import '@cypress/code-coverage/support';
+// ***********************************************************
+// This example support/e2e.ts is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands';
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/index-back.html b/index-back.html
new file mode 100644
index 0000000..7392526
--- /dev/null
+++ b/index-back.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ RS-REACT-TS
+
+
+
+
+
+
diff --git a/index.html b/index.html
index 7392526..266f561 100644
--- a/index.html
+++ b/index.html
@@ -7,7 +7,8 @@
RS-REACT-TS
-
-
+ not rendered
+
+