Skip to content
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
6 changes: 5 additions & 1 deletion .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@ on:
push:
branches: [main]
paths:
- 'static/nginxaas-azure/js/cost-calculator_v2.js'
- 'static/nginxaas-azure/js/cost-calculator_v2.js'
- 'content/nginxaas-azure/billing/usage-and-cost-estimator.md'
- 'static/nginxaas-google/js/cost-calculator_gc.js'
- 'content/nginxaas-google/billing/usage-and-cost-estimator.md'
pull_request:
paths:
- 'static/nginxaas-azure/js/cost-calculator_v2.js'
- 'content/nginxaas-azure/billing/usage-and-cost-estimator.md'
- 'static/nginxaas-google/js/cost-calculator_gc.js'
- 'content/nginxaas-google/billing/usage-and-cost-estimator.md'
permissions:
contents: read
jobs:
Expand Down
15 changes: 12 additions & 3 deletions content/nginxaas-google/billing/usage-and-cost-estimator.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,25 @@ nd-product: NGOOGL
{{< raw-html >}}
<link rel="stylesheet" href="/nginxaas-google/css/cost-calculator_v2.css">
<div id="calculator">
<h3 id="calculator-section-heading">
<h3 id="calculator-section-heading" data-testid="calculator-section-heading">
Cost Estimation for Enterprise Plan
<button id="printButton">Print Estimate</button>
</h3>

<div class="section">
<div class="section" data-testid="calculator-section-content">
<div class="form-section">
<div class="form-section-content">
<h4 id="calculator-section-heading">Estimate Monthly Cost</h4>

<div class="form-field">
<label for="tierSelect">Tier</label>
<select id="tierSelect">
<option value="tier1">Tier 1</option>
<option value="tier2">Tier 2</option>
<option value="tier3">Tier 3</option>
</select>
</div>

<div class="form-field">
<label for="numNcus">NCUs</label>
<input id="numNcus" type="number" step="10" min="10" />
Expand All @@ -42,7 +51,7 @@ nd-product: NGOOGL
<div class="form-section-content">
<div id="totals-section">
<span class="total-text">Total Monthly Payment</span>
<span id="total-value" class="total-text">--</span>
<span id="total-value" class="total-text" data-testid="total-value">--</span>

<details id="total-cost-details">
<summary>Show calculations</summary>
Expand Down
52 changes: 38 additions & 14 deletions static/nginxaas-google/js/cost-calculator_gc.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
// /nginxaas-google/js/cost-calculator_v2.js
(() => {
// ---- Single-tier pricing ----
const costs = {
fixedHourly: 0.10, // $/hour
ncuHourly: 0.008, // $/NCU/hour
dataPerGb: 0.0096 // $/GB (monthly)
// ---- Multi-tier pricing ----
const tierCosts = {
tier1: {
fixedHourly: 0.10, // $/hour
ncuHourly: 0.008, // $/NCU/hour
dataPerGb: 0.0096 // $/GB (monthly)
},
tier2: {
fixedHourly: 0.133,
ncuHourly: 0.0106,
dataPerGb: 0.0127
},
tier3: {
fixedHourly: 0.166,
ncuHourly: 0.0132,
dataPerGb: 0.0159
}
};
let currentTier = "tier1";
let costs = tierCosts[currentTier];

const utils = {
calculateCost: (costs, values) => {
Expand All @@ -31,6 +45,7 @@

// ---- Element refs ----
const costFormElements = {
tierSelect: document.getElementById("tierSelect"),
numNcus: document.getElementById("numNcus"),
numHours: document.getElementById("numHours"),
dataProcessedGb: document.getElementById("dataProcessedGb"),
Expand All @@ -47,11 +62,17 @@
};

// ---- Listeners ----
const setupChangeListeners = (costs, values = calculatorValuesState) => {
const setupChangeListeners = (values = calculatorValuesState) => {
Object.keys(costFormElements).forEach((elName) => {
costFormElements[elName].addEventListener("change", (evt) => {
values[elName] = Number(evt.target.value);
updateCost(costs);
if (elName === "tierSelect") {
currentTier = evt.target.value;
costs = tierCosts[currentTier];
updateCost(costs, values);
} else {
values[elName] = Number(evt.target.value);
updateCost(costs, values);
}
});
});

Expand All @@ -65,7 +86,11 @@
Object.keys(costFormElements).forEach((elName) => {
const el = costFormElements[elName];
if (el && (el.tagName.toLowerCase() === "input" || el.tagName.toLowerCase() === "select")) {
el.value = values[elName];
if (elName === "tierSelect") {
el.value = currentTier;
} else {
el.value = values[elName];
}
}
});
};
Expand All @@ -74,10 +99,10 @@
const updateCost = (costs, values = calculatorValuesState) => {
const updatedTotalCost = utils.calculateCost(costs, values);
document.getElementById("total-value").textContent = utils.currencyFormatter(updatedTotalCost);
updateTotalCostDetails(values, updatedTotalCost);
updateTotalCostDetails(values, updatedTotalCost, costs);
};

const updateTotalCostDetails = (formValues, totalCost) => {
const updateTotalCostDetails = (formValues, totalCost, costs) => {
totalCostDetailElements.hours.textContent = formValues.numHours;
totalCostDetailElements.ncus.textContent = formValues.numNcus;
totalCostDetailElements.fixedHourly.textContent = utils.currencyFormatter(costs.fixedHourly, 3);
Expand All @@ -99,10 +124,9 @@

// ---- Boot ----
const start = async () => {
const loaded = costs;
setupChangeListeners(loaded);
setupChangeListeners();
initializeValues(calculatorValuesState);
updateCost(loaded); // immediately show total on load
updateCost(costs, calculatorValuesState); // immediately show total on load
};
start();
})();
26 changes: 26 additions & 0 deletions tests/src/n4g-calculator.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { expect, test } from "@playwright/test";
import { handleConsentPopup, waitFor } from "../util";

test.describe("Testing for N4G calculator page", () => {
test.beforeEach(async ({ page }) => {
await page.goto("/nginxaas/google/billing/usage-and-cost-estimator/");
await page.waitForLoadState("load");
await waitFor(async () => await handleConsentPopup(page));
});

test("calculator renders", async ({ page }) => {
const header = page.getByTestId("calculator-section-heading");
const content = page.getByTestId("calculator-section-content");

await expect(header).toBeVisible();
await expect(content).toBeVisible();
});

test("calculator values render", async ({ page }) => {
// Conjunction - If outputs are rendered, it is safe to say the inputs are rendered.
// NOT testing changing numbers will impact the total values as that should be the job of unit tests. This is just a smoke tests.
const totalValue = page.getByTestId("total-value");

expect(await totalValue.textContent()).toBeTruthy();
});
});
Loading