8000 Jest testing by jakeymac · Pull Request #1163 · tethysplatform/tethys · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Jest testing #1163

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

Draft
wants to merge 29 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
2ccef84
initial commit, added jest files
jakeymac Feb 4, 2025
d0e7320
added jest test for datable_view and select_input gizmos, updated con…
jakeymac Feb 6, 2025
5536f7c
added testing for slide_sheet
jakeymac Feb 6, 2025
75a7f68
added frontend testing for toggle_switch gizmo
jakeymac Feb 6, 2025
e41ae12
added testing for range_slider gizmo - may need to look at public_int…
jakeymac Feb 6, 2025
c5879f1
added testing for gizmo_utilities file
jakeymac Feb 7, 2025
7c65357
initial testing for cesium_map_view
jakeymac Feb 11, 2025
5480be5
added jest testing to CI
jakeymac Feb 11, 2025
dab9124
removed caching in frontend testing
jakeymac Feb 12, 2025
f882d9a
moved js_tests folder to main tests folder
jakeymac Feb 19, 2025
cd7b5cf
moved test configuration and dependency files to js_tests folder
jakeymac Feb 19, 2025
71e5000
Updated testing to use Testing Library
jakeymac Feb 22, 2025
6a8863b
Cleaned up code
jakeymac Feb 23, 2025
2134313
Fixed template name in slide sheet tests
jakeymac Feb 23, 2025
23ab98e
Added testing for range_slider gizmo
jakeymac Feb 23, 2025
d51495c
Added testing for datatable_view gizmo
jakeymac Feb 24, 2025
68e076a
clean up code
jakeymac Feb 24, 2025
4670bc7
Testing progress for select_input gizmo
jakeymac Mar 21, 2025
8dea3b1
Fixed render template script
jakeymac Mar 22, 2025
74c8d79
fix for front end testing in CI
jakeymac Mar 22, 2025
194786e
fix for CI testing
jakeymac Mar 22, 2025
6c47881
added django dependency for running front end tests
jakeymac Mar 22, 2025
dbdba08
CI Update
jakeymac Mar 23, 2025
f82d667
fix for frontend tests CI job
jakeymac Mar 23, 2025
ce1501c
CI fix
jakeymac Mar 24, 2025
ed05e01
Test fix + black fix
jakeymac Mar 24, 2025
a0a871f
fix in frontend testing configuration
jakeymac Mar 24, 2025
ee3cc29
fixes in frontend testing configuration
jakeymac Apr 1, 2025
257b755
Toggle switch testing added
jakeymac Apr 1, 2025
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
36 changes: 36 additions & 0 deletions .github/workflows/tethys.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,42 @@ jobs:
conda activate tethys
coveralls --service=github

frontend-tests:
name: Frontend Tests
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v4

- name: Set Up Node.js
uses: actions/setup-node@v3
with:
node-version: 18

- name: Set Up Python
uses: actions/setup-python@v4
with:
python-version: '3.12'

- name: Install Tethys and Dependencies
run: |

bash scripts/install_tethys.sh --partial-tethys-install meds -n tethys -s $PWD -x -d 5.1 --python-version 3.12
. ~/miniconda/etc/profile.d/conda.sh
conda activate tethys
python -m pip install --upgrade pip

- name: Install Dependencies
run: npm install
working-directory: tests/js_tests

- name: Run Tests
run: |
. ~/miniconda/etc/profile.d/conda.sh
conda activate tethys
npm test
working-directory: tests/js_tests

docker-build:
name: Docker Build (${{ matrix.platform }}, ${{ matrix.django-version }}, ${{ matrix.python-version }})
runs-on: ${{ matrix.platform }}
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,7 @@ tethys_portal/_version.py
# Required for docs build
git-lfs-*/*
conda.recipe/meta.yaml

jest_coverage/
package-lock.json
tests/js_tests/rendered_templates
3 changes: 3 additions & 0 deletions tests/js_tests/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"presets": ["@babel/preset-env"]
}
46 changes: 46 additions & 0 deletions tests/js_tests/__mocks__/cesium.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
module.exports = {
Viewer: jest.fn().mockImplementation(() => ({
scene: {
globe: {},
primitives: { add: jest.fn() },
},
camera: {
setView: jest.fn(),
flyTo: jest.fn(),
lookAt: jest.fn(),
lookAtTransform: jest.fn(),
viewBoundingSphere: jest.fn(),
},
imageryLayers: { addImageryProvider: jest.fn() },
terrainProvider: jest.fn(),
entities: { add: jest.fn() },
clock: {},
dataSources: { add: jest.fn() },
trackedEntity: null,
})),
Ion: { defaultAccessToken: "mock_token" },
ClockViewModel: jest.fn(),
WebMapServiceImageryProvider: jest.fn(),
JulianDate: {
fromIso8601: jest.fn(),
toIso8601: jest.fn(),
},
GeoJsonDataSource: {
load: jest.fn(),
},
CzmlDataSource: {
load: jest.fn(),
},
TimeIntervalCollection: {
fromIso8601DateArray: jest.fn(),
},
Cartesian3: jest.fn(),
Color: jest.fn(),
HorizontalOrigin: {},
VerticalOrigin: {},
PointGraphics: jest.fn(),
Material: {
fromType: jest.fn(),
},
};

63 changes: 63 additions & 0 deletions tests/js_tests/gizmos/datatable_view.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { execSync } from "child_process";
import fs from "fs";
import path from "path";
const { screen } = require("@testing-library/dom");

import $ from "jquery";

import DataTable from "datatables.net";
$.fn.DataTable = DataTable;

import TETHYS_DATATABLE_VIEW from "../../../tethys_gizmos/static/tethys_gizmos/js/datatable_view.js";

global.TETHYS_DATATABLE_VIEW = TETHYS_DATATABLE_VIEW;

global.Node = window.Node;
global.Option = window.Option || function Option() {};

let renderedHtml = '';

const DATATABLE_VIEW_ID = "test_datatable_view_id";

beforeAll(() => {
const templateName = "tethys_gizmos/gizmos/datatable_view.html";
const context = JSON.stringify({
title: "Testing the datatable view gizmo",
id: DATATABLE_VIEW_ID,

column_names: ["Column 1", "Column 2", "Column 3"],
rows: [
["Row 1 Column 1", "Row 1 Column 2", "Row 1 Column 3"],
["Row 2 Column 1", "Row 2 Column 2", "Row 2 Column 3"],
["Row 3 Column 1", "Row 3 Column 2", "Row 3 Column 3"],
]

});

execSync(`python render_template.py ${templateName} '${context}' `, { stdio: "inherit" });

const outputPath = path.resolve("./rendered_templates/test_datatable_view_output.html");
renderedHtml = fs.readFileSync(outputPath, "utf8");
});

beforeEach(() => {
document.body.innerHTML = renderedHtml;

// Initialize datatable view
TETHYS_DATATABLE_VIEW.initTableView(".data_table_gizmo_view");
});

test("Gizmo renders correctly", () => {
expect(screen.getByText("Column 1")).toBeInTheDocument();
expect(screen.getByText("Column 2")).toBeInTheDocument();
expect(screen.getByText("Column 3")).toBeInTheDocument();
expect(screen.getByText("Row 1 Column 1")).toBeInTheDocument();
expect(screen.getByText("Row 1 Column 2")).toBeInTheDocument();
expect(screen.getByText("Row 1 Column 3")).toBeInTheDocument();
});

test("Datatable is initialized", () => {
const dataTable = document.querySelector(".data_table_gizmo_view");
expect(dataTable).toHaveClass("dataTable");
});

57 changes: 57 additions & 0 deletions tests/js_tests/gizmos/range_slider.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { execSync } from "child_process";
import fs from "fs";
import path from "path";
import { screen, fireEvent } from "@testing-library/dom";
import "@testing-library/jest-dom";
import $ from "jquery";

import TETHYS_RANGE_SLIDER from "../../../tethys_gizmos/static/tethys_gizmos/js/range_slider.js";

global.TETHYS_RANGE_SLIDER = TETHYS_RANGE_SLIDER;

let renderedHtml = "";
const RANGE_SLIDER_ID = "test-range-slider";

beforeAll(() => {
const templateName = "tethys_gizmos/gizmos/range_slider.html";
const context = JSON.stringify({
name: RANGE_SLIDER_ID,
display_text: "Select Range",
min: 0,
max: 100,
step: 5,
initial: 50,
});

// Render the template with the context
execSync(`python render_template.py ${templateName} '${context}' `, { stdio: "inherit" });

const outputPath = path.resolve("./rendered_templates/test_range_slider_output.html");

// Read the rendered HTML
renderedHtml = fs.readFileSync(outputPath, "utf8");
});

beforeEach(() => {
document.body.innerHTML = renderedHtml;

// Initialize range slider and add event listeners
TETHYS_RANGE_SLIDER.init_range_sliders();
});

test("Gizmo renders correctly", () => {
expect(screen.getByLabelText("Select Range")).toBeInTheDocument();
expect(screen.getByRole("slider")).toBeInTheDocument();
});

test("Range slider updates display text", () => {
const rangeSliderInput = document.getElementById(RANGE_SLIDER_ID);
const rangeSliderDisplay = rangeSliderInput.nextElementSibling;

// Test for initial value
expect(rangeSliderDisplay).toHaveTextContent("50");

// Test for updated value with input
fireEvent.input(rangeSliderInput, { target: { value: 75 } });
expect(rangeSliderDisplay).toHaveTextContent("75");
});
64 changes: 64 additions & 0 deletions tests/js_tests/gizmos/select_input.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { execSync } from "child_process";
import path from "path";
import fs from "fs";

const { screen } = require("@testing-library/dom");
import userEvent from "@testing-library/user-event";

import TETHYS_SELECT_INPUT from "../../../tethys_gizmos/static/tethys_gizmos/js/select_input.js";

import $ from "jquery";
global.$ = $;
global.jQuery = $;

$.fn.select2 = jest.fn().mockImplementation(function () {
return this;
});

let renderedHtml = "";

beforeAll(() => {
const templateName = "tethys_gizmos/gizmos/select_input.html";
const context = JSON.stringify({
title: "Testing the select input gizmo",
id: "test_select_input_id",
options: [
["Option 1", "option1"],
["Option 2", "option2"],
["Option 3", "option3"],
],
initial: "option2",
display_text: "Choose an Option",
name: "test_selector"
});

execSync(`python render_template.py ${templateName} '${context}'`, { stdio: "inherit" });
const outputPath = path.resolve("./rendered_templates/test_select_input_output.html");
renderedHtml = fs.readFileSync(outputPath, "utf8");
})

beforeEach(() => {
document.body.innerHTML = renderedHtml;
TETHYS_SELECT_INPUT.initSelectInput(".tethys-select2");
});

test("Gizmo renders correctly", () => {
expect(screen.getByText("Option 1")).toBeInTheDocument();
expect(screen.getByText("Option 2")).toBeInTheDocument();
expect(screen.getByText("Option 3")).toBeInTheDocument();
});

test("The initially selected value is visible to the user", () => {
const select = screen.getByLabelText("Choose an Option");
expect(select).toHaveDisplayValue("Option 2");
});


test("User can select a different option", async () => {
const user = userEvent.setup();
const select = screen.getByLabelText("Choose an Option");

await user.selectOptions(select, "option3");

expect(select).toHaveDisplayValue("Option 3");
});
87 changes: 87 additions & 0 deletions tests/js_tests/gizmos/slide_sheet.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { execSync } from "child_process";
import fs from "fs";
import path from "path";
const { screen, fireEvent } = require("@testing-library/dom");

import SLIDE_SHEET from "../../../tethys_gizmos/static/tethys_gizmos/js/slide_sheet.js"

window.SLIDE_SHEET = SLIDE_SHEET;

let renderedHtml = '';

const SLIDE_SHEET_ID = "test_slide_sheet_id"

function simulateShowClassStyling() {
// Simulate the CSS class 'show' to display or hide the slide sheet
// To be used in the tests any time a slide sheet is opened or closed
// manually or with a simulated button press
document.querySelectorAll('.slide-sheet').forEach((element) => {
if (element.classList.contains('show')) {
element.style.display = 'block';
}
else {
element.style.display = 'none';
}
});
}

beforeAll(() => {
// Render the template using Python script with a provided context
const templateName = "tethys_gizmos/gizmos/slide_sheet.html";
const context = JSON.stringify({
title: "Testing the slide sheet gizmo",
id: SLIDE_SHEET_ID,
content_template: "test_template.html"
});
execSync(`python render_template.py ${templateName} '${context}' `, { stdio: "inherit" });
// Read the rendered HTML file
const outputPath = path.resolve("./rendered_templates/test_slide_sheet_output.html");
renderedHtml = fs.readFileSync(outputPath, "utf8");
})

beforeEach(() => {
// Set up the document body with the rendered HTML before each test runs
document.body.innerHTML = renderedHtml;
});

test("Gizmo renders correctly", () => {
const sheet = document.getElementById(SLIDE_SHEET_ID);
expect(sheet).toBeInTheDocument();
expect(sheet).toHaveClass("slide-sheet");
});

test("Clicking the open button should show the slide sheet", async () => {
const sheet = document.getElementById(SLIDE_SHEET_ID);
// Make sure the sheet is not visible to start off
expect(sheet).not.toBeVisible();
// Add a button to open the slide sheet
const button = document.createElement("button");
button.className = "btn-open";
button.textContent = "Open Slide Sheet";
document.body.appendChild(button);
// Add an event listener to the button to open the slide sheet
const openButton = screen.getByText("Open Slide Sheet");
openButton.addEventListener("click", () => {
SLIDE_SHEET.open(SLIDE_SHEET_ID);
});
fireEvent.click(openButton);
simulateShowClassStyling();
// Check that the slide sheet is now visible
expect(sheet).toBeVisible();
});


test("Clicking the close button should hide the slide sheet", async () => {
// Open the slide sheet first
SLIDE_SHEET.open(SLIDE_SHEET_ID);
simulateShowClassStyling();
const sheet = document.getElementById(SLIDE_SHEET_ID);
// Make sure the sheet is visible to start off
expect(sheet).toBeVisible();
// Now close it
const closeButton = document.querySelector(".btn-close");
fireEvent.click(closeButton);
simulateShowClassStyling();
// Check that the sheet is no longer visible
expect(sheet).not.toBeVisible();
});
Loading
0