-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9770599
commit aebefce
Showing
16 changed files
with
107 additions
and
149 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,64 +1,71 @@ | ||
import { activeFilterClass, imgDownloadTimeoutMS } from '@ts/constants.ts'; | ||
|
||
before(() => { | ||
const FIXTURES_PATH = 'tests/cypress/fixtures'; | ||
const DOWNLOADS_PATH = 'tests/cypress/downloads'; | ||
const INITIAL_CSS_MATRIX = 'matrix(1, 0, 0, 1, 0, 0)'; | ||
const INITIAL_CSS_FILTERS = 'brightness(1) grayscale(0) blur(0px) hue-rotate(0deg) opacity(1) contrast(1) saturate(1) sepia(0)'; | ||
|
||
beforeEach(() => { | ||
cy.visit('/'); | ||
|
||
cy.get('[data-test="rotate_left"]').as('rotateLeftBtn'); | ||
cy.get('[data-test="vertical_flip"]').as('verticalFlipBtn'); | ||
cy.get('[data-test="rotate_right"]').as('rotateRightBtn'); | ||
cy.get('[data-test="grayscale"]').as('grayscaleFilterBtn'); | ||
cy.get('[data-test="img_select_label"]').as('imgSelectLabel'); | ||
cy.get('#filters_container').children().first().as('firstFilterBtn'); | ||
}); | ||
|
||
it('goes through the process of uploading, editing, and downloading multiple images', () => { | ||
/* Initial state */ | ||
it('initial UI state', () => { | ||
cy.get('#edit_options_container').should('be.disabled'); | ||
cy.get('#img_save_anchor').should('have.attr', 'aria-disabled', 'true'); | ||
}); | ||
|
||
/* Upload an image */ | ||
cy.get('@imgSelectLabel').selectFile('tests/cypress/fixtures/sh.png').trigger('cancel'); | ||
cy.get('@imgSelectLabel').selectFile('tests/cypress/fixtures/pickle-rick.webp'); | ||
it('upload, edit, and download multiple images', () => { | ||
/* Upload an image. */ | ||
cy.get('@imgSelectLabel').selectFile(`${FIXTURES_PATH}/pickle-rick.webp`).trigger('cancel'); | ||
cy.get('@imgSelectLabel').selectFile(`${FIXTURES_PATH}/pickle-rick.webp`); | ||
cy.get('#edit_options_container').should('be.enabled'); | ||
cy.get('#reset_filters_btn').should('be.disabled'); | ||
cy.get('#img_save_anchor').should('have.attr', 'aria-disabled', 'true'); | ||
cy.get('#img').should('have.attr', 'alt', 'pickle-rick.webp').and('have.attr', 'title', 'pickle-rick.webp'); | ||
|
||
/* Edit the uploaded image */ | ||
/* Edit the uploaded image. */ | ||
cy.get('@verticalFlipBtn').click(); | ||
cy.get('@rotateRightBtn').click(); | ||
cy.get('@grayscaleFilterBtn').click(); | ||
cy.get('@firstFilterBtn').should('not.have.class', activeFilterClass); | ||
cy.get('@grayscaleFilterBtn').should('have.class', activeFilterClass); | ||
cy.get('#active_filter_range_input').invoke('val', 100); | ||
cy.get('#active_filter_range_input').trigger('input'); | ||
cy.get('#img').should('have.css', 'filter', 'brightness(1) grayscale(1) blur(0px) hue-rotate(0deg) opacity(1) contrast(1) saturate(1) sepia(0)'); | ||
cy.get('#reset_filters_btn').should('be.enabled'); | ||
cy.get('#img_save_anchor').should('have.attr', 'aria-disabled', 'false'); | ||
cy.get('@rotateRightBtn').click(); | ||
cy.get('@verticalFlipBtn').click(); | ||
cy.get('@firstFilterBtn').should('not.have.class', activeFilterClass); | ||
cy.get('@grayscaleFilterBtn').should('have.class', activeFilterClass); | ||
cy.get('#img').should('have.css', 'transform', 'matrix(0, 1, 1, 0, 0, 0)'); | ||
cy.get('#img').should('have.css', 'filter', 'brightness(1) grayscale(1) blur(0px) hue-rotate(0deg) opacity(1) contrast(1) saturate(1) sepia(0)'); | ||
|
||
/* Download the edited image */ | ||
/* Download the edited image. */ | ||
cy.get('#img_save_anchor').click(); | ||
cy.get('#img_save_anchor').should('have.text', 'Saving...'); | ||
cy.get('#img_save_anchor').should('have.attr', 'aria-disabled', 'true'); | ||
cy.wait(imgDownloadTimeoutMS); | ||
cy.get('#img_save_anchor').should('have.text', 'Save Image'); | ||
cy.readFile('tests/cypress/downloads/pickle-rick (edited).webp'); | ||
cy.readFile(`${DOWNLOADS_PATH}/pickle-rick (edited).webp`).should('exist'); | ||
|
||
/* Upload another image */ | ||
cy.get('#img_drop_zone').selectFile('tests/cypress/fixtures/landscape.jpg', { action: 'drag-drop' }); | ||
cy.get('@grayscaleFilterBtn').should('not.have.class', activeFilterClass); | ||
/* Upload another image. */ | ||
cy.get('#img_drop_zone').selectFile(`${FIXTURES_PATH}/landscape.jpg`, { action: 'drag-drop' }); | ||
cy.get('@firstFilterBtn').should('have.class', activeFilterClass); | ||
|
||
cy.get('@grayscaleFilterBtn').should('not.have.class', activeFilterClass); | ||
cy.get('#filters_container').should(({ 0: filtersContainer }) => { | ||
expect(filtersContainer?.scrollLeft).to.equal(0); | ||
}); | ||
|
||
/* Manually reset edits */ | ||
cy.get('@rotateLeftBtn').click(); | ||
cy.get('#img').should('have.css', 'transform', 'matrix(0, -1, 1, 0, 0, 0)'); | ||
/* Manually reset applied edits. */ | ||
cy.get('@rotateRightBtn').click(); | ||
cy.get('@grayscaleFilterBtn').click(); | ||
cy.get('#active_filter_range_input').invoke('val', 100); | ||
cy.get('#active_filter_range_input').trigger('input'); | ||
cy.get('#reset_filters_btn').click(); | ||
cy.get('#img').should('have.css', 'transform', 'matrix(1, 0, 0, 1, 0, 0)'); | ||
cy.get('#reset_filters_btn').should('be.disabled'); | ||
cy.get('#img_save_anchor').should('have.attr', 'aria-disabled', 'true'); | ||
cy.get('#img').should('have.css', 'transform', INITIAL_CSS_MATRIX); | ||
cy.get('#img').should('have.css', 'filter', INITIAL_CSS_FILTERS); | ||
}); |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,9 @@ | ||
import { test, expect } from 'vitest'; | ||
import { imgStore } from '@ts/imgStore.ts'; | ||
import { it, expect, describe } from 'vitest'; | ||
|
||
describe('imgStore.activeFilter', () => { | ||
it('should update the active filter based on the given name, and allow access to its properties', () => { | ||
const activeFilterName = 'grayscale'; | ||
imgStore.activeFilter = activeFilterName; | ||
test('updates the active filter based on the given name, and allows access to its properties', () => { | ||
const activeFilterName = 'grayscale'; | ||
imgStore.activeFilter = activeFilterName; | ||
|
||
expect(imgStore.activeFilter.name).toBe(activeFilterName); | ||
}); | ||
expect(imgStore.activeFilter.name).toBe(activeFilterName); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,10 @@ | ||
import { test, expect } from 'vitest'; | ||
import { imgStore } from '@ts/imgStore.ts'; | ||
import { it, expect, describe } from 'vitest'; | ||
|
||
describe('imgStore.isEdited', () => { | ||
it('should return “true” if the image has been rotated', () => { | ||
const rotationDegs = [-450, -270, -180, -90, 90, 180, 270, 450] as const; | ||
const rotationDegs = [-450, -270, -180, -90, 90, 180, 270, 450] as const; | ||
|
||
rotationDegs.forEach((rotationDeg) => { | ||
imgStore.state.rotationDeg = rotationDeg; | ||
test.each(rotationDegs)('%i° rotates the image', (rotationDeg) => { | ||
imgStore.state.rotationDeg = rotationDeg; | ||
|
||
expect(imgStore.isEdited).toBeTruthy(); | ||
}); | ||
}); | ||
expect(imgStore.isEdited).toBeTruthy(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,10 @@ | ||
import { test, expect } from 'vitest'; | ||
import { imgStore } from '@ts/imgStore.ts'; | ||
import { it, expect, describe } from 'vitest'; | ||
|
||
describe('imgStore.isLandscape', () => { | ||
it('should return “true” if the image has been rotated only by multiples of 90 degrees and not 180 degrees', () => { | ||
const rotationDegs = [-450, -270, -90, 90, 270, 450] as const; | ||
const rotationDegs = [-450, -270, -90, 90, 270, 450] as const; | ||
|
||
rotationDegs.forEach((rotationDeg) => { | ||
imgStore.state.rotationDeg = rotationDeg; | ||
test.each(rotationDegs)('%i° is a multiple of 90°, but not that of 180°; so the image is landscaped', (rotationDeg) => { | ||
imgStore.state.rotationDeg = rotationDeg; | ||
|
||
expect(imgStore.isLandscape).toBeTruthy(); | ||
}); | ||
}); | ||
expect(imgStore.isLandscape).toBeTruthy(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,15 @@ | ||
import { test, expect } from 'vitest'; | ||
import { imgStore } from '@ts/imgStore.ts'; | ||
import { it, expect, describe } from 'vitest'; | ||
import { deepClone } from '@ts/utils/deepClone.ts'; | ||
import { resetRotationDeg } from '@ts/utils/resetRotationDeg.ts'; | ||
|
||
describe('imgStore.reset', () => { | ||
it('should correctly reset the state', () => { | ||
const initialState = deepClone(imgStore.state); | ||
const [name, extension, rotationDeg] = ['New Image', 'png', 180]; | ||
const adjustedRotationDeg = resetRotationDeg(rotationDeg); | ||
test('resets the state', () => { | ||
const initialState = deepClone(imgStore.state); | ||
const [name, extension, rotationDeg] = ['New Image', 'png', 180]; | ||
const adjustedRotationDeg = resetRotationDeg(rotationDeg); | ||
|
||
Object.assign(imgStore.state, { name, extension, rotationDeg, verticalFlip: -1 }); | ||
imgStore.reset(); | ||
Object.assign(imgStore.state, { name, extension, rotationDeg, verticalFlip: -1 }); | ||
imgStore.reset(); | ||
|
||
expect(imgStore.state).toStrictEqual({ ...initialState, name, extension, rotationDeg: adjustedRotationDeg }); | ||
}); | ||
expect(imgStore.state).toStrictEqual({ ...initialState, name, extension, rotationDeg: adjustedRotationDeg }); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,8 @@ | ||
import { test, expect } from 'vitest'; | ||
import { imgStore } from '@ts/imgStore.ts'; | ||
import { it, expect, describe } from 'vitest'; | ||
|
||
describe('imgStore.title', () => { | ||
it('should set the name and extension of the image file, and return its full name (name.extension)', () => { | ||
Object.assign(imgStore.state, { name: 'New Image', extension: 'png' }); | ||
test('sets the name and the extension of the image file, then returns “name.extension”', () => { | ||
Object.assign(imgStore.state, { name: 'New Image', extension: 'png' }); | ||
|
||
expect(imgStore.title).toMatchInlineSnapshot(`"New Image.png"`); | ||
}); | ||
expect(imgStore.title).toMatchInlineSnapshot(`"New Image.png"`); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,10 @@ | ||
import { test, expect } from 'vitest'; | ||
import { imgStore } from '@ts/imgStore.ts'; | ||
import { it, expect, describe } from 'vitest'; | ||
|
||
describe('imgStore.updateCSSFilters', () => { | ||
it('should create and/or update the CSS filters string corresponding with filter values', () => { | ||
imgStore.state.filters.find(({ name }) => name === 'grayscale')!.value = 50; | ||
imgStore.updateCSSFilters(); | ||
const { CSSFilters } = imgStore.state; | ||
test('creates the CSS filters string corresponding with filter values', () => { | ||
imgStore.state.filters.find(({ name }) => name === 'grayscale')!.value = 50; | ||
imgStore.updateCSSFilters(); | ||
const { CSSFilters } = imgStore.state; | ||
|
||
expect(CSSFilters).toMatchInlineSnapshot(`"brightness(100%)grayscale(50%)blur(0px)hue-rotate(0deg)opacity(100%)contrast(100%)saturate(100%)sepia(0%)"`); | ||
}); | ||
expect(CSSFilters).toMatchInlineSnapshot(`"brightness(100%)grayscale(50%)blur(0px)hue-rotate(0deg)opacity(100%)contrast(100%)saturate(100%)sepia(0%)"`); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,18 @@ | ||
import { test, expect } from 'vitest'; | ||
import { imgStore } from '@ts/imgStore.ts'; | ||
import { spinModes } from '@ts/constants.ts'; | ||
import { it, expect, describe } from 'vitest'; | ||
import { spinIsRotation } from '@ts/utils/spinIsRotation.ts'; | ||
|
||
describe('imgStore.updateSpinValue', () => { | ||
it('should update the rotation degree and vertical/horizontal flip values', () => { | ||
spinModes.forEach((spinMode) => { | ||
imgStore.updateSpinValue(spinMode); | ||
test.each(spinModes)('“%s” updates the rotation degree or vertical/horizontal flip', (spinMode) => { | ||
imgStore.updateSpinValue(spinMode); | ||
|
||
const { rotationDeg, verticalFlip, horizontalFlip } = imgStore.state; | ||
const { rotationDeg, verticalFlip, horizontalFlip } = imgStore.state; | ||
|
||
if (spinIsRotation(spinMode)) { | ||
expect(rotationDeg === 0 || rotationDeg % 90 === 0).toBeTruthy(); | ||
} else { | ||
expect([1, -1]).toContain(verticalFlip); | ||
expect([1, -1]).toContain(horizontalFlip); | ||
} | ||
}); | ||
}); | ||
// eslint-disable-next-line test/no-conditional-in-test | ||
if (spinIsRotation(spinMode)) { | ||
expect(rotationDeg === 0 || rotationDeg % 90 === 0).toBeTruthy(); | ||
} else { | ||
expect([1, -1]).toContain(verticalFlip); | ||
expect([1, -1]).toContain(horizontalFlip); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,16 @@ | ||
import { it, expect, describe } from 'vitest'; | ||
import { test, expect } from 'vitest'; | ||
import { deepClone } from '@ts/utils/deepClone.ts'; | ||
|
||
describe('deepClone', () => { | ||
it('should create a deep clone of the given object', () => { | ||
const obj = { | ||
a: 1, | ||
b: true, | ||
c: 'value', | ||
d: { e: 'f' }, | ||
g: [1, '2', { h: '3' }], | ||
}; | ||
const clone = deepClone(obj); | ||
test('creates a deep clone of the given object', () => { | ||
const obj = { | ||
a: 1, | ||
b: true, | ||
c: 'value', | ||
d: { e: 'f' }, | ||
g: [1, '2', { h: '3' }], | ||
}; | ||
const clone = deepClone(obj); | ||
|
||
expect(clone).not.toBe(obj); | ||
expect(clone).toStrictEqual(obj); | ||
}); | ||
expect(clone).not.toBe(obj); | ||
expect(clone).toStrictEqual(obj); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,11 @@ | ||
import { it, expect, describe } from 'vitest'; | ||
import { test, expect } from 'vitest'; | ||
import { resetRotationDeg } from '@ts/utils/resetRotationDeg.ts'; | ||
import { rotationDegs as baseRotationDegs } from '@ts/constants.ts'; | ||
|
||
describe('resetRotationDeg', () => { | ||
it('should reset the rotation degree to a multiple of 360 degrees', () => { | ||
const fullRotationDeg = 360; | ||
const rotationDegs = [-450, -360, -270, -180, -90, 0, 90, 180, 270, 360, 450]; | ||
const rotationDegs = [-450, -360, -270, -180, -90, 0, 90, 180, 270, 360, 450]; | ||
|
||
rotationDegs.forEach((rotationDeg) => { | ||
const adjustedRotationDeg = resetRotationDeg(rotationDeg); | ||
test.each(rotationDegs)('%i° is reset to a multiple of 360°', (rotationDeg) => { | ||
const adjustedRotationDeg = resetRotationDeg(rotationDeg); | ||
|
||
expect(adjustedRotationDeg % fullRotationDeg).toBe(0); | ||
}); | ||
}); | ||
expect(adjustedRotationDeg % baseRotationDegs.full).toBe(0); | ||
}); |
Oops, something went wrong.