Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/workflows/cypress_integration_testing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Cypress Tests

on:
workflow_dispatch:
schedule:
cron: 45 4 1 */1 *

jobs:
tap_testing:
runs-on: ubuntu-latest
strategy:
matrix:
resource_type: [water, food, foraging, bathroom]
steps:
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Checkout
uses: actions/checkout@v4
- name: Cypress run
uses: cypress-io/github-action@v6
with:
start: yarn start:cypress
browser: chrome
spec: cypress/integration/desktop/tapcheck.${{ matrix.resource_type }}.cy.js
config-file: cypress.integration.config.mjs
35 changes: 35 additions & 0 deletions cypress.integration.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { defineConfig } from 'cypress';
import { createClient } from '@supabase/supabase-js';

const databaseUrl = 'https://wantycfbnzzocsbthqzs.supabase.co';
const resourceDatabaseName = 'resources';
const databaseApiKey = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6IndhbnR5Y2Zibnp6b2NzYnRocXpzIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MzcwNDY2OTgsImV4cCI6MjA1MjYyMjY5OH0.yczsMOx3Y-zsWu-GjYEajIb0yw9fYWEIUglmmfM1zCY';

const supabase = createClient(databaseUrl, databaseApiKey);

async function getResources() {
const { data, error } = await supabase.from(resourceDatabaseName).select('*');
if (error) {
throw error;
}
return data;
}

export default defineConfig({
e2e: {
setupNodeEvents(on, config) {
on('task', {
getResources,
log(message) {
console.log(message)

return null
}
})
},
watchForFileChanges: false,
specPattern: 'cypress/integration/desktop/*.cy.{js,jsx,ts,tsx}',
baseUrl: 'http://localhost:5173',
video: true
}
});
76 changes: 76 additions & 0 deletions cypress/integration/desktop/tapcheck.bathroom.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Primary Goal: Test each tap in without incurring heavy use of the Maps API, such as loading dynamic maps multiple times

// - Builds a queue of all RESOURCE_TYPE locations
// - While the queue is not empty, pulls an item from the queue and tests clicking it
// - If the site crashes, records the tap that crashed, reloads the site, and continues looping

const RESOURCE_TYPE = "BATHROOM"

let exception_ocurred = false;
let exception_message = "";

// For each resource type, test each site detail permutation and confirm only the expected number of taps appear.
describe('site info', () => {
beforeEach(() => {
cy.visit('/');
});

it(`should tap through all ${RESOURCE_TYPE} sites`, () => {
let test_target_queue = [5, 4, 3, 2, 1];
let test_target_failures = [];

cy.on('uncaught:exception', (err, runnable) => {
exception_message = err.message;
exception_ocurred = true;
return false;
})

const testLocation = () => {
const target_location_id = test_target_queue.pop()
cy.task('log', `Testing ${target_location_id}`)
cy.get(`[title=data-cy-${target_location_id}]`).click({ force: true, timeout: 8000 }).then(() => {
cy.task('log', `Tested location ${target_location_id}`)
if (!exception_ocurred) {
cy.get('[data-cy=close-selected-tap] > button').click()
}
else {
cy.task('log', `An error ocurred when loading location ${target_location_id}: ${exception_message}`)
test_target_failures.push(target_location_id)
cy.reload()
cy.switchResourceType(RESOURCE_TYPE)
cy.zoomMapOutMax()
}
if (test_target_queue.length == 0) {
cy.task('log', `Errors ocurred when loading the following ${test_target_failures.length} locations: ${test_target_failures}`)

if (test_target_failures.length > 0) {
throw new Error(`Errors ocurred when loading the following locations: ${test_target_failures}`)
}
return
}
exception_ocurred = false
exception_message = "";

cy.wait(2000, { log: false })
testLocation()
})
}

cy.switchResourceType(RESOURCE_TYPE)
cy.zoomMapOutMax()

cy.task('getResources').then((resources) => {
let water_resources = resources.filter((resource) => resource['resource_type'] === RESOURCE_TYPE)
test_target_queue = [...Array(water_resources.length).keys()]
cy.task('log', `test_target_queue: ${test_target_queue}`)

// For targeted debugging
// test_target_queue = [106, 107, 108, 109, 110];

exception_ocurred = false;
exception_message = "";
testLocation()
})
});
}
);
76 changes: 76 additions & 0 deletions cypress/integration/desktop/tapcheck.food.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Primary Goal: Test each tap in without incurring heavy use of the Maps API, such as loading dynamic maps multiple times

// - Builds a queue of all RESOURCE_TYPE locations
// - While the queue is not empty, pulls an item from the queue and tests clicking it
// - If the site crashes, records the tap that crashed, reloads the site, and continues looping

const RESOURCE_TYPE = "FOOD"

let exception_ocurred = false;
let exception_message = "";

// For each resource type, test each site detail permutation and confirm only the expected number of taps appear.
describe('site info', () => {
beforeEach(() => {
cy.visit('/');
});

it(`should tap through all ${RESOURCE_TYPE} sites`, () => {
let test_target_queue = [5, 4, 3, 2, 1];
let test_target_failures = [];

cy.on('uncaught:exception', (err, runnable) => {
exception_message = err.message;
exception_ocurred = true;
return false;
})

const testLocation = () => {
const target_location_id = test_target_queue.pop()
cy.task('log', `Testing ${target_location_id}`)
cy.get(`[title=data-cy-${target_location_id}]`).click({ force: true, timeout: 8000 }).then(() => {
cy.task('log', `Tested location ${target_location_id}`)
if (!exception_ocurred) {
cy.get('[data-cy=close-selected-tap] > button').click()
}
else {
cy.task('log', `An error ocurred when loading location ${target_location_id}: ${exception_message}`)
test_target_failures.push(target_location_id)
cy.reload()
cy.switchResourceType(RESOURCE_TYPE)
cy.zoomMapOutMax()
}
if (test_target_queue.length == 0) {
cy.task('log', `Errors ocurred when loading the following ${test_target_failures.length} locations: ${test_target_failures}`)

if (test_target_failures.length > 0) {
throw new Error(`Errors ocurred when loading the following locations: ${test_target_failures}`)
}
return
}
exception_ocurred = false
exception_message = "";

cy.wait(2000, { log: false })
testLocation()
})
}

cy.switchResourceType(RESOURCE_TYPE)
cy.zoomMapOutMax()

cy.task('getResources').then((resources) => {
let water_resources = resources.filter((resource) => resource['resource_type'] === RESOURCE_TYPE)
test_target_queue = [...Array(water_resources.length).keys()]
cy.task('log', `test_target_queue: ${test_target_queue}`)

// For targeted debugging
// test_target_queue = [106, 107, 108, 109, 110];

exception_ocurred = false;
exception_message = "";
testLocation()
})
});
}
);
76 changes: 76 additions & 0 deletions cypress/integration/desktop/tapcheck.foraging.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Primary Goal: Test each tap in without incurring heavy use of the Maps API, such as loading dynamic maps multiple times

// - Builds a queue of all RESOURCE_TYPE locations
// - While the queue is not empty, pulls an item from the queue and tests clicking it
// - If the site crashes, records the tap that crashed, reloads the site, and continues looping

const RESOURCE_TYPE = "FORAGE"

let exception_ocurred = false;
let exception_message = "";

// For each resource type, test each site detail permutation and confirm only the expected number of taps appear.
describe('site info', () => {
beforeEach(() => {
cy.visit('/');
});

it(`should tap through all ${RESOURCE_TYPE} sites`, () => {
let test_target_queue = [5, 4, 3, 2, 1];
let test_target_failures = [];

cy.on('uncaught:exception', (err, runnable) => {
exception_message = err.message;
exception_ocurred = true;
return false;
})

const testLocation = () => {
const target_location_id = test_target_queue.pop()
cy.task('log', `Testing ${target_location_id}`)
cy.get(`[title=data-cy-${target_location_id}]`).click({ force: true, timeout: 8000 }).then(() => {
cy.task('log', `Tested location ${target_location_id}`)
if (!exception_ocurred) {
cy.get('[data-cy=close-selected-tap] > button').click()
}
else {
cy.task('log', `An error ocurred when loading location ${target_location_id}: ${exception_message}`)
test_target_failures.push(target_location_id)
cy.reload()
cy.switchResourceType(RESOURCE_TYPE)
cy.zoomMapOutMax()
}
if (test_target_queue.length == 0) {
cy.task('log', `Errors ocurred when loading the following ${test_target_failures.length} locations: ${test_target_failures}`)

if (test_target_failures.length > 0) {
throw new Error(`Errors ocurred when loading the following locations: ${test_target_failures}`)
}
return
}
exception_ocurred = false
exception_message = "";

cy.wait(2000, { log: false })
testLocation()
})
}

cy.switchResourceType(RESOURCE_TYPE)
cy.zoomMapOutMax()

cy.task('getResources').then((resources) => {
let water_resources = resources.filter((resource) => resource['resource_type'] === RESOURCE_TYPE)
test_target_queue = [...Array(water_resources.length).keys()]
cy.task('log', `test_target_queue: ${test_target_queue}`)

// For targeted debugging
// test_target_queue = [106, 107, 108, 109, 110];

exception_ocurred = false;
exception_message = "";
testLocation()
})
});
}
);
76 changes: 76 additions & 0 deletions cypress/integration/desktop/tapcheck.water.cy.js
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we able to create a reusable function that we can use for each tap rather than repeating the same pattern over 4 different files?

Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Primary Goal: Test each tap in without incurring heavy use of the Maps API, such as loading dynamic maps multiple times

// - Builds a queue of all RESOURCE_TYPE locations
// - While the queue is not empty, pulls an item from the queue and tests clicking it
// - If the site crashes, records the tap that crashed, reloads the site, and continues looping

const RESOURCE_TYPE = "WATER"

let exception_ocurred = false;
let exception_message = "";

// For each resource type, test each site detail permutation and confirm only the expected number of taps appear.
describe('site info', () => {
beforeEach(() => {
cy.visit('/');
});

it(`should tap through all ${RESOURCE_TYPE} sites`, () => {
let test_target_queue = [5, 4, 3, 2, 1];
let test_target_failures = [];

cy.on('uncaught:exception', (err, runnable) => {
exception_message = err.message;
exception_ocurred = true;
return false;
})

const testLocation = () => {
const target_location_id = test_target_queue.pop()
cy.task('log', `Testing ${target_location_id}`)
cy.get(`[title=data-cy-${target_location_id}]`).click({ force: true, timeout: 8000 }).then(() => {
cy.task('log', `Tested location ${target_location_id}`)
if (!exception_ocurred) {
cy.get('[data-cy=close-selected-tap] > button').click()
}
else {
cy.task('log', `An error ocurred when loading location ${target_location_id}: ${exception_message}`)
test_target_failures.push(target_location_id)
cy.reload()
cy.switchResourceType(RESOURCE_TYPE)
cy.zoomMapOutMax()
}
if (test_target_queue.length == 0) {
cy.task('log', `Errors ocurred when loading the following ${test_target_failures.length} locations: ${test_target_failures}`)

if (test_target_failures.length > 0) {
throw new Error(`Errors ocurred when loading the following locations: ${test_target_failures}`)
}
return
}
exception_ocurred = false
exception_message = "";

cy.wait(2000, { log: false })
testLocation()
})
}

cy.switchResourceType(RESOURCE_TYPE)
cy.zoomMapOutMax()

cy.task('getResources').then((resources) => {
let water_resources = resources.filter((resource) => resource['resource_type'] === RESOURCE_TYPE)
test_target_queue = [...Array(water_resources.length).keys()]
cy.task('log', `test_target_queue: ${test_target_queue}`)

// For targeted debugging
// test_target_queue = [106, 107, 108, 109, 110];

exception_ocurred = false;
exception_message = "";
testLocation()
})
});
}
);
13 changes: 13 additions & 0 deletions cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,16 @@
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })

Cypress.Commands.add('switchResourceType', (resourceType) => {
cy.get('[data-cy=button-resource-type-menu]').click()
cy.get(`[data-cy=button-${resourceType}-data-selector]`).click()
cy.get('[data-cy=button-resource-type-menu]').click()
})

Cypress.Commands.add('zoomMapOutMax', () => {
// Zoom out the map to allow all taps to be rendered globally
for (let n = 0; n < 15; n++) {
cy.get('div > [title="Zoom out"]').click()
}
})
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@
},
"scripts": {
"start": "vite",
"start:cypress": "VITE_CYPRESS_TEST=true yarn start",
"start:cypress": "VITE_CYPRESS_TEST=true VITE_GMAP_OPTIMIZED=false yarn start",
"start:integration": "VITE_GMAP_OPTIMIZED=false yarn start",
"build": "vite build",
"testDataGen": "node cypress/testDataGenerator.js",
"test": "yarn testDataGen && cypress run",
Expand Down
Loading