Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Schema files to download zip #174

Merged
merged 9 commits into from
Jun 26, 2023
Merged
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ delete.bat
model/build/Mask*
model/build/taco*
tags
frontend/yarn.lock
2 changes: 1 addition & 1 deletion frontend/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Dockerfile for trash-ai frontend

# Stage 1: Build the project
FROM node:16.12.0 as builder
FROM node:16.20.0 as builder

# Set the working directory
WORKDIR /app
Expand Down
5 changes: 5 additions & 0 deletions frontend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,10 @@ yarn build
yarn lint
```

### Run Cypress Tests
```
yarn run cypress open
```

### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
62 changes: 62 additions & 0 deletions frontend/__tests__/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Tests and Verifications

## Automatic Tests

### Scenarios
1. Does the landing pag load?
2. On hitting show samples, does processing complete in an expected amount of time? Does it show all the results expected?
3. After recieving results, can you click an image and does the page show the expected data/metadata/etc?
4. After recieving results, does the summary page contain the correct data?

## How to run

1. Navigate to `frontend/`
2. Run `yarn install`
2. Spin up docker container
`docker-compose up`
3. Run the auto tests
`yarn run jest`

## Manual Tests

1. Does the landing pag load?

When you open the landing page. Either at https://www.trashai.org/ or http://localhost:5150

The page should loads in a reasonable timeframe. (<2 seconds)

*You can use the `Network` tab in the dev tools for more fine grained analysis.*

2. On hitting show samples, does processing complete in an expected amount of time? Does it show all the results expected?

When the show samples button is pressed. (as depicted below)
![Instructions](misc/Show_Samples_Button.png "Show Title Button")

Then the app will start processing images. (as depcited below)
![Processing](misc/Processing_Samples.png "Processing Samples Progress Bar")

*The processing should be relatively quick, it it takes more than a minute, something is definetly wrong.*

When the processing is done, the results will be available in the summary page.

![Summary ](misc/Summary_Of_Samples.png "Summary of Sample Results")

It should be populated like above.

3. After recieving results, can you click an image and does the page show the expected data/metadata/etc?

When one of the links in the summary table is clicked.

![Open images](misc/Open_images.png "Open Images")

Then the images will be displayed along with the segmentation and classes detected.

![List Images](misc/Images_with_Segmentation.png "List Images")

When the METADATA tab is opened, the relevant metadata for the image is displayed.

![View Metadata](misc/Viewing_Metadata.png "View Metadata")

4. After recieving results, does the summary page contain the correct data?

*The summary page shows the results of processing a random sample of images, as long as it's not empty it can be considered as correct.*
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/__tests__/misc/Open_images.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/__tests__/misc/Processing_Samples.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions frontend/__tests__/misc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*placeholder*
Binary file added frontend/__tests__/misc/Show_Samples_Button.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/__tests__/misc/Summary_Of_Samples.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/__tests__/misc/Viewing_Metadata.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
110 changes: 110 additions & 0 deletions frontend/__tests__/smokeTest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/* eslint-disable no-undef */
const timeout = 12000
const url = 'http://localhost:5150/'

describe(
'Smoke test for Trash-AI',
() => {
let page
beforeAll(async () => {
page = await global.__BROWSER__.newPage()
await page.setViewport({
width: 1536,
height: 960,
})
await page.goto(url)
}, timeout)

afterAll(async () => {
await page.close()
})

it('should load without error', async () => {
const text = await page.evaluate(() => document.body.textContent)
expect(text).toContain('Trash AI')
})

it(
'should show samples when prompted',
async () => {
// Open actions menu
const openActionsBtn = await page.waitForSelector(
'#actions-button-test-id',
)
await openActionsBtn.click()
await page.waitForTimeout(1000)

// Click Show Samples
const showSamplesBtn = await page.waitForSelector(
'#show-samples-test-id',
)
await showSamplesBtn.click()
await page.waitForTimeout(2000)

// Navigate to Summary page
const summaryBtn = await page.waitForSelector(
'#summary-tab-test-id',
)
await summaryBtn.click()
await page.waitForTimeout(500)

// Check if navigations was successful
current_url = await page.url()
expect(current_url).toBe(`${url}summary/detections`)

// Check if results are displayed
const drinkCanImg = await page.waitForSelector(
'a[href="/detection/Drink%20can"]',
)
await drinkCanImg.click()
await page.waitForTimeout(500)

// Check if navigation happened
current_url = await page.url()
expect(current_url).toBe(`${url}detection/Drink%20can`)

// Navigate to image view page
const sampleImg = await page.waitForSelector(
'div[id="sample01.jpg-test-id"]',
)
await sampleImg.click()
await page.waitForTimeout(500)

// Check if navigation happened
current_url = await page.url()
expect(current_url).toBe(`${url}image/0/image`)

// Check if the image is loaded
const canvasImg = await page.waitForSelector('#canvasparent')

// Check of the images classes are loaded
const drinkCanClass = await page.waitForSelector(
'a[href="/detection/Drink%20can"]',
)

const paperCupClass = await page.waitForSelector(
'a[href="/detection/Paper%20cup"]',
)

// Check of the image and metadata tabs are loaded
const imageTab = await page.waitForSelector(
'#image-tab-test-id',
)

const metadataTab = await page.waitForSelector(
'#meta-tab-test-id',
)
metadataTab.click()
await page.waitForTimeout(500)

// Check is exif data is displayed
const exifData = await page.waitForSelector('#exifData-test-id')
// Check if metadata is displayed
const metaData = await page.waitForSelector('#metaData-test-id')
await page.waitForTimeout(500)
},
timeout,
)
},
timeout,
)
8 changes: 8 additions & 0 deletions frontend/cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { defineConfig } from "cypress";

export default defineConfig({
e2e: {
baseUrl: "https://www.trashai.org/",
pageLoadTimeout: 3000
},
});
5 changes: 5 additions & 0 deletions frontend/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
globalSetup: './setup.js',
globalTeardown: './teardown.js',
testEnvironment: './puppeteer_environment.js',
}
7 changes: 6 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"serve": "vite preview",
"build": "vite build",
"lint": "vue-cli-service lint",
"dev": "vite"
"dev": "vite",
"test": "jest"
},
"dependencies": {
"@fawmi/vue-google-maps": "^0.9.72",
Expand All @@ -23,11 +24,14 @@
"dexie": "^3.2.2",
"file-saver": "^2.0.5",
"fuse.js": "^6.6.2",
"jest": "^29.5.0",
"jszip": "^3.10.0",
"loglevel": "^1.8.0",
"p-queue": "^7.3.0",
"pinia": "^2.0.17",
"pinia-plugin-persistedstate": "^1.6.3",
"puppeteer": "^20.7.1",
"rimraf": "^5.0.1",
"roboto-fontface": "^0.10.0",
"rxjs": "^7.5.7",
"ts-exif-parser": "^0.2.2",
Expand Down Expand Up @@ -56,6 +60,7 @@
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-vue": "^9.2.0",
"jest-puppeteer": "^9.0.0",
"prettier": "^2.7.1",
"sass": "^1.53.0",
"typescript": "^4.7.4",
Expand Down
82 changes: 82 additions & 0 deletions frontend/public/schema/image_schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"hash": { "type": "string" },
"filename": { "type": "string" },
"exifdata": {
"type": "object",
"properties": {
"Make": { "type": "string" },
"Model": { "type": "string" },
"DateTimeOriginal": { "type": "integer" },
"ModifyDate": { "type": "integer" },
"CreateDate": { "type": "integer" },
"GPSLatitudeRef": { "type": "string" },
"GPSLatitude": { "type": "number" },
"GPSLongitudeRef": { "type": "string" },
"GPSLongitude": { "type": "number" },
"GPSAltitudeRef": { "type": "integer" },
"GPSAltitude": { "type": "number" },
"GPSTimeStamp": {
"type": "array",
"items": { "type": "integer" }
},
"GPSDateStamp": { "type": "string" },
"ExifImageWidth": { "type": "integer" },
"ExifImageHeight": { "type": "integer" }
},
"required": [
"Make",
"Model",
"DateTimeOriginal",
"ModifyDate",
"CreateDate",
"GPSLatitudeRef",
"GPSLatitude",
"GPSLongitudeRef",
"GPSLongitude",
"GPSAltitudeRef",
"GPSAltitude",
"GPSTimeStamp",
"GPSDateStamp",
"ExifImageWidth",
"ExifImageHeight"
]
},
"metadata": {
"type": "array",
"items": {
"type": "object",
"properties": {
"score": { "type": "string" },
"correction": { "type": "string" },
"remove": { "type": "boolean" },
"is_tf": { "type": "boolean" },
"id": { "type": "string" },
"label": { "type": "string" },
"area": {
"type": "object",
"properties": {
"x1": { "type": "number" },
"y1": { "type": "number" },
"x2": { "type": "number" },
"y2": { "type": "number" }
},
"required": ["x1", "y1", "x2", "y2"]
}
},
"required": [
"score",
"correction",
"remove",
"is_tf",
"id",
"label",
"area"
]
}
}
},
"required": ["hash", "filename", "exifdata", "metadata"]
}
38 changes: 38 additions & 0 deletions frontend/public/schema/image_schema.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Image Schema Description

**hash** (String): A hash associated with the image file.

**filename** (String): The filename of the image.

**exifdata** (Object): An object that contains EXIF data with the following properties:

- **Make** (String): The manufacturer of the camera that took the image.
- **Model** (String): The camera model that took the image.
- **DateTimeOriginal** (Integer): The original date and time the image was taken, represented as a Unix timestamp.
- **ModifyDate** (Integer): The date and time the image was last modified, represented as a Unix timestamp.
- **CreateDate** (Integer): The date and time the image was created, represented as a Unix timestamp.
- **GPSLatitudeRef** (String): The reference for latitude (usually "N" or "S").
- **GPSLatitude** (Number): The latitude coordinate of where the image was taken.
- **GPSLongitudeRef** (String): The reference for longitude (usually "E" or "W").
- **GPSLongitude** (Number): The longitude coordinate of where the image was taken.
- **GPSAltitudeRef** (Integer): The reference for altitude (usually 0).
- **GPSAltitude** (Number): The altitude where the image was taken.
- **GPSTimeStamp** (Array): The GPS timestamp of when the image was taken, represented as an array of integers [hours, minutes, seconds].
- **GPSDateStamp** (String): The GPS date when the image was taken.
- **ExifImageWidth** (Integer): The width of the original image.
- **ExifImageHeight** (Integer): The height of the original image.

**metadata** (Array): An array of objects where each object represents a detected item with the following properties:

- **score** (String): The confidence score of the AI model for the detection.
- **correction** (String): A correction applied to the AI model's prediction. This is usually empty if no correction is applied.
- **remove** (Boolean): A flag indicating whether this detection should be removed. False means the detection is valid.
- **is_tf** (Boolean): A flag indicating if the detection is a true positive (true) or false positive (false).
- **id** (String): A unique identifier for the detection.
- **label** (String): The label of the detected item (e.g., "Plastic film").
area (Object): An object that contains the coordinates of the detected area with the following properties:
- **x1** (Number): The x-coordinate of the top left corner of the detected area.
- **y1** (Number): The y-coordinate of the top left corner of the detected area.
- **x2** (Number): The x-coordinate of the bottom right corner of the detected area.
- **y2** (Number): The y-coordinate of the bottom right corner of the detected area.
Please note that all of the properties described above are required. If any property is missing or if a property's value is of an incorrect type, the JSON will not validate against the schema.
Loading