Skip to content

Commit

Permalink
Admins can preview pollen calendar (#101)
Browse files Browse the repository at this point in the history
  • Loading branch information
HuzzNZ authored May 5, 2024
2 parents acea5c2 + 49147a4 commit 68afb64
Show file tree
Hide file tree
Showing 21 changed files with 1,693 additions and 162 deletions.
18 changes: 12 additions & 6 deletions cypress.config.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { defineConfig } from "cypress";
import { defineConfig } from "cypress"
import { configureVisualRegression } from "cypress-visual-regression/dist/plugin"

export default defineConfig({
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
configureVisualRegression(on)
},
env: {
visualRegressionType: "regression",
},
screenshotsFolder: "./cypress/snapshots/actual",
},
},
});
})
139 changes: 139 additions & 0 deletions cypress/e2e/cms/pollenCalendar.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import { URLS } from "../consts"
import { loginAttempt, mockValidCredentials, userIsLoggedIn } from "../authenticationUtils"

function loginToEditPollenPage() {
cy.visit(URLS.EDIT_POLLEN_DATA)
mockValidCredentials()
loginAttempt()
userIsLoggedIn()
cy.visit(URLS.EDIT_POLLEN_DATA) // TODO: login should already redirect here (task #70)
cy.url().should("eq", URLS.EDIT_POLLEN_DATA)
}

function inputDataFile(filepath: string = "cypress/fixtures/Pollen Dummy Data - valid format.xlsx") {
cy.contains("label", "Upload .xlsx Excel spreadsheet containing pollen data")
.find("input[type='file']")
.selectFile(filepath)
}

describe("updating pollen calendar", () => {
beforeEach(loginToEditPollenPage)

it("successfully preview calendar using valid excel spreadsheet", () => {
inputDataFile("cypress/fixtures/Pollen Dummy Data - valid format.xlsx")

cy.contains("button", "Preview data").click()
cy.contains("Preview generated ✅")

cy.contains("button", "Update calendar on website").click()
})

describe("invalid filetypes", () => {
it("no file", () => {
cy.contains("label", "Upload .xlsx Excel spreadsheet containing pollen data").find("input[type='file']")

cy.contains("button", "Preview data").click()
cy.contains("No file uploaded.")
cy.contains("Preview generated ✅").should("not.exist")
})

it("invalid file", () => {
inputDataFile("cypress/fixtures/authSuccessResponse.json")

cy.contains("button", "Preview data").click()
cy.contains("Uploaded file 'authSuccessResponse.json' is not a .xlsx Excel spreadsheet.")
})
})

describe("invalid excel spreadsheet format", () => {
// invalid formatsare formats that ignore an assumptions made by parsing algorithm

it("has no worksheets with 'raw' in the name", () => {
inputDataFile("cypress/fixtures/Pollen Dummy Data - invalid format - no 'raw' worksheet.xlsx")

cy.contains("button", "Preview data").click()
cy.contains(
"This spreadsheet has no worksheet with 'raw' in its name. Names of the worksheets in this spreadsheet: 2022_23_percentage, 2023_24, 2023_24_percentage, 2022_23_old"
)
cy.contains("Preview generated ✅").should("not.exist")
})

it("pollen types are not in column A", () => {
inputDataFile("cypress/fixtures/Pollen Dummy Data - invalid format - pollen types in column B.xlsx")

cy.contains("button", "Preview data").click()
cy.contains(
`Cell A2 doesn't seem to be a pollen name: undefined. Values in Column A from Row 2 onwards are expected to be pollen names, and the value in the last populated Row in Column A should be "Total pollen counted".`
)
cy.contains("Preview generated ✅").should("exist") // the other worksheet has a valid format though so preview that data
})

it.skip("dates are not in row 1", () => {
inputDataFile("cypress/fixtures/Pollen Dummy Data - invalid format - dates in row 2.xlsx")

cy.contains("button", "Preview data").click()
cy.contains("Cell B1 doesn't seem to be a date: Pollen Data 2025.")
cy.contains("Preview generated ✅").should("exist") // other worksheet has valid format
})

it("doesn't have 'Total pollen counted'", () => {
inputDataFile(
"cypress/fixtures/Pollen Dummy Data - invalid format - sheets don't have 'Total pollen counted'.xlsx"
)

cy.contains("button", "Preview data").click()
cy.contains("Worksheet '2023_24_raw' couldn't be parsed because this error occurred:")
cy.contains("A cell containing 'Total pollen counted' was not found in Column A.")
cy.contains("Preview generated ✅").should("not.exist")
})
})

describe("showing calendar preview", () => {
beforeEach(() => inputDataFile("cypress/fixtures/Pollen Dummy Data - valid format.xlsx"))

// both tests won't work as is because canvas is a visual element
// and its children elements are picked up by the browser :`(
it.skip("chart with a labelled x and y axis", () => {
cy.contains("button", "Preview data").click()

const yAxisLabel = "Pollen grains per cubic metre of air"
const xAxisLabel = "Date"
cy.contains(yAxisLabel).should("have.length", 1)
cy.contains(xAxisLabel).should("have.length", 1)
})

it.skip("check tooltip of a pollen data point", () => {
cy.contains("button", "Preview data").click()

cy.get("#toolTipButton").trigger("mouseover")

cy.contains("You hovered over the Button").should("be.visible")
})

it("pollen calendar looks as it currently does lol", () => {
cy.contains("button", "Preview data").click()
cy.wait(5000)

// if it looks '50%' or more different to base snapshot then test fails
cy.compareSnapshot("editPollenCalendarPreview", { errorThreshold: 50 })
cy.get("canvas").compareSnapshot("editPollenCalendarPreview", { errorThreshold: 50 })
})

it("pollen calendar hover on data point should look as it does right now", () => {
cy.contains("button", "Preview data").click()
cy.wait(5000)

cy.get("canvas").then(($canvas) => {
const canvasWidth = $canvas.width()
const canvasHeight = $canvas.height()

let buttonX = canvasWidth * 0.53052
let buttonY = canvasHeight * 0.6427

cy.wrap($canvas).scrollIntoView().realTouch({ x: buttonX, y: buttonY })
cy.wait(5000)
cy.get("canvas").compareSnapshot("pollenCalendarDataPointHover1")
})
})
})
})
97 changes: 0 additions & 97 deletions cypress/e2e/cms/pollenData.cy.ts

This file was deleted.

Binary file not shown.
2 changes: 2 additions & 0 deletions cypress/snapshots/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
actual
diff
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 8 additions & 4 deletions cypress/support/e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,17 @@
// ***********************************************************

// Import commands.js using ES2015 syntax:
import './commands'
import "./commands"

Cypress.on('uncaught:exception', (err, runnable) => {
import "cypress-real-events/support"
import { addCompareSnapshotCommand } from "cypress-visual-regression/dist/command"
addCompareSnapshotCommand()

Cypress.on("uncaught:exception", (err, runnable) => {
// returning false here prevents Cypress from
// failing the test
return false
})
})

// Alternatively you can use CommonJS syntax:
// require('./commands')
// require('./commands')
7 changes: 7 additions & 0 deletions cypress/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"compilerOptions": {
"esModuleInterop": true,
"types": ["cypress", "cypress-visual-regression", "cypress-real-events"],
"resolveJsonModule": true
}
}
34 changes: 34 additions & 0 deletions frontend/app/(cms)/pollen/components/DateInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import dayjs from "dayjs"

export default function DateInput({ lowerLimit, upperLimit, setUpperLimit, setLowerLimit }: any) {
const lowerLimitString = dayjs(lowerLimit).format("YYYY-MM-DD")
const upperLimitString = dayjs(upperLimit).format("YYYY-MM-DD")

function makeTimestampForDateMidday(timestamp: number) {
return dayjs(timestamp).set("hour", 0).set("minute", 0).set("second", 0).set("millisecond", 0).valueOf()
}

return (
<div>
<label className="form-label">
From
<input
className="form-input"
type="date"
defaultValue={lowerLimitString}
onChange={(e) => setLowerLimit(makeTimestampForDateMidday(e.target.valueAsNumber))}
/>
</label>

<label className="form-label">
to
<input
className="form-input"
type="date"
defaultValue={upperLimitString}
onChange={(e) => setUpperLimit(makeTimestampForDateMidday(e.target.valueAsNumber))}
/>
</label>
</div>
)
}
Loading

0 comments on commit 68afb64

Please sign in to comment.