diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 2577e37..3cba00b 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -1,4 +1,4 @@ -name: Deploy static site to Pages +name: Deploy Next.js site to Pages on: push: @@ -29,10 +29,22 @@ jobs: with: enablement: true + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Build + run: npm run build + - name: Upload artifact uses: actions/upload-pages-artifact@v3 with: - path: . + path: ./out deploy: needs: build diff --git a/.gitignore b/.gitignore index 3dc844d..986fc8d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,18 @@ -public/ -resources/ -.hugo_build.lock - -# OS / editor +/node_modules +/.pnp +.pnp.js +/coverage +/.next/ +/out/ +/build .DS_Store +desktop.ini Thumbs.db -.vscode/ +*.pem +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.env*.local +.vercel +*.tsbuildinfo +next-env.d.ts diff --git a/README.md b/README.md deleted file mode 100644 index 6dfb94e..0000000 --- a/README.md +++ /dev/null @@ -1 +0,0 @@ -# TestOpsEngineering diff --git a/contact.html b/contact.html deleted file mode 100644 index 52949d0..0000000 --- a/contact.html +++ /dev/null @@ -1,139 +0,0 @@ - - - - - - - -Contact — TestOps Engineering - - - - - - - -
-
- TestOps Engineering logoTestOps Engineering - Back to site -
-
- -
-
-

Contact

-

Tell me about your QA goals

-

Share your current setup, problems, and timeline. I'll review and send back a scoped recommendation and quote.

-

Before publishing: replace YOUR_EMAIL@example.com in the form action with your email.

-
- -
- - - - - -
-
- - -
-
- - -
-
- -
-
- - -
-
- - -
-
- -
-
- - -
-
- - -
-
- -
- - -
- - -
-
- - - - diff --git a/index.html b/index.html deleted file mode 100644 index 5b6ca20..0000000 --- a/index.html +++ /dev/null @@ -1,1478 +0,0 @@ - - - - - - - - - - - - - -TestOps Engineering — QA & Automation Consulting - - - - - - - - - - - - -
-
-

Quality Engineering · Test Automation · AI-Assisted Testing

-
- - -
-

- Your team ships fast.
- We make sure it doesn't
break
in production. -

-

- TestOps Engineering brings senior-level QA strategy, automation, and AI-assisted testing - to startups and growing tech teams — without the overhead of a full-time hire. -

- - -
- - -
-
-
-
-
-
- testops-audit v2 — zsh -
-
-
$ testops audit --ai-scan --full
-
# Scanning coverage layers...
-
unit_coverage 87%  ✓ healthy
-
api_coverage 34%  ⚠ gap detected
-
e2e_flakiness 22%  ✗ critical
-
# AI model test coverage...
-
llm_eval_tests none  ✗ missing
-
prompt_regress none  ✗ missing
-
# CI pipeline analysis...
-
avg_build_time 18m 43s ⚠ slow
-
parallelization none   ✗ opportunity
-
✓ Roadmap generated — 12 findings
-
$
-
-
-
- -
-
-
- - -
-
-
- Engineering background from -
- - - - - -
-
-
-
- - -
-
- -

Built for teams that are moving fast
and need quality to keep up

-

Not every team needs a full-time QA lead. Many just need someone who's done it at scale — and can get them there without the overhead.

-
- -
-

Startups · Seed–Series B

-

You're shipping fast with no QA process

-

Your engineers test their own code, CI is slow or flaky, and you've had a production incident you shouldn't have. You need QA infrastructure built from scratch — right the first time.

-
- -
-

Mid-size Tech · 50–500 eng

-

Your automation exists, but it's not working

-

You have tests, but they're flaky, slow, or nobody trusts them. Your CI pipeline is a black box. You need someone to audit, fix, and hand it back — properly documented and owned by your team.

-
- -
-

AI & ML Product Teams

-

You're shipping AI features with no eval strategy

-

Your product has LLM-powered features, but there's no regression strategy for prompts or model behavior. You need AI-aware QA — a fast-growing gap most consultants can't fill.

-
- -
-
-
- - -
-
- -

Everything from audit
to full automation build

-

Engagements are scoped, time-boxed, and documented. Your team owns everything after handoff — no dependency on us.

- -
- -
-

QA Audit & Roadmap

-

Current-state assessment

-

A structured review of your test pyramid, CI pipeline, and coverage gaps — with a prioritized 30/60/90-day plan your engineering team can actually execute.

-
    -
  • Test pyramid health check
  • -
  • CI/CD signal analysis
  • -
  • Risk-based coverage gap mapping
  • -
  • Prioritized improvement roadmap
  • -
-
- -
-

Test Automation

-

Frameworks built to last

-

From API contract tests to full E2E suites. Designed for maintainability, parallelization, and fast feedback — not just to check a box.

-
    -
  • API + UI automation (Python, Appium)
  • -
  • CI integration & quality gates
  • -
  • Parallelization & reporting
  • -
  • Android / ADB tooling
  • -
-
- -
-

Release Quality & Reliability

-

Stop flaky tests killing CI

-

Systematic flakiness reduction, stabilization, and observability improvements so your CI signal means something — and your team trusts it again.

-
    -
  • Flaky test triage & quarantine
  • -
  • Root-cause debugging
  • -
  • Failure observability setup
  • -
  • Stabilization backlog planning
  • -
-
- -
- In demand 2026 -

AI & LLM Testing

-

Eval strategy for AI-powered products

-

Most teams shipping AI features have no regression strategy for prompt behavior or model outputs. We build eval pipelines, prompt regression suites, and LLM quality gates.

-
    -
  • LLM eval framework design
  • -
  • Prompt regression testing
  • -
  • Model output validation
  • -
  • AI feature QA strategy
  • -
-
- -
- - -
-
-

AI-assisted testing is not a trend — it's the new baseline

-

89% of engineering orgs are piloting AI in their QA processes in 2026. Only 15% have done it right. We help teams bridge that gap with pragmatic, production-ready AI testing strategies — not vendor hype.

-
- AI-ready practice -
- -
-
- - -
-
- -

From first call to shipped improvement

-

A focused engagement model that respects your sprint calendar and delivers results in weeks, not quarters.

-
- -
-
- 01 · Discovery -

Free 30-minute call

-

We learn your stack, your pain points, and your timeline. No prep deck required — just bring your problems.

-
- -
-
- 02 · Proposal -

Scoped, fixed-price plan

-

Clear deliverables, timeline, and price. No hourly billing. No scope surprises. You approve before any work begins.

-
- -
-
- 03 · Engagement -

Async-first, embedded work

-

Weekly check-ins. We work in your tools — Jira, Slack, GitHub. No overhead. Just execution.

-
- -
-
- 04 · Handoff -

Full docs, your team owns it

-

Everything documented. No dependency on us. Your team runs it forward independently from day one.

-
- -
-
-
- - -
-
- -

Real problems,
real outcomes

-

Across Google Pixel, Meta, Apple, Samsung, and Hulu. These are the kinds of problems we solve.

- -
- -
-
-

Mobile · Reliability · CI

-

Reduced flaky test rate from 22% to under 3%

-

A mobile hardware team shipping weekly was blocked by unreliable CI — false failures eating 6+ hours of eng time per sprint. Introduced a quarantine policy, stabilization backlog, and diagnostic reruns with structured logging. Eliminated two release-blocking incidents in the first month.

-
- Android · ADB - Python - CI/CD - Mobile hardware -
-

* Replace these metrics with your real numbers before going live

-
-
-
- −86% - Flakiness rate -
-
- - Release velocity -
-
- 6h - Saved per sprint -
-
-
- -
-
-

API Coverage · Regression

-

Built API test coverage catching regressions missed by UI-only suite

-

UI-only test suite was missing regressions in backend flows. Built a contract testing layer with data setup helpers and CI quality gates. Caught 3 production-bound bugs in the first week — before they reached staging or customers.

-
- Postman - Charles Proxy - Python - API testing -
-

* Replace these metrics with your real numbers before going live

-
-
-
- +61% - API coverage -
-
- 3 - Bugs caught wk 1 -
-
-
- -
-
-
- - -
-
- -

Tools we work with

-

Add or remove anything that doesn't match your actual stack before going live.

-
-
PythonAutomation
-
AppiumMobile UI
-
ADBAndroid
-
Charles ProxyNetwork
-
JenkinsCI/CD
-
GitHub ActionsCI/CD
- -
Android StudioMobile
-
LLM EvalsAI testing
-
-
-
- - -
-
- -

Scoped engagements,
custom quote

-

Every project is different. Share your goals through the Contact page and I'll send a tailored scope and quote.

- -
- -
-

QA Audit

-
    -
  • 1-week engagement
  • -
  • Test pyramid assessment
  • -
  • CI/CD pipeline review
  • -
  • Written findings report
  • -
  • 30/60/90-day roadmap
  • -
  • 1 follow-up call included
  • -
- Contact for quote → -
- - - -
-

AI & LLM Testing

-
    -
  • LLM eval framework setup
  • -
  • Prompt regression test coverage
  • -
  • Model output validation criteria
  • -
  • Safety and edge-case test design
  • -
  • CI quality gates for AI features
  • -
  • Actionable reporting for releases
  • -
- Contact for quote → -
- -
- -

Not sure which engagement fits? Use the Contact page and I'll recommend the best starting point.

-
-
- - - - - - - - - diff --git a/next.config.js b/next.config.js new file mode 100644 index 0000000..1c8496a --- /dev/null +++ b/next.config.js @@ -0,0 +1,9 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + output: 'export', + images: { + unoptimized: true, + }, +} + +module.exports = nextConfig diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..aa477e2 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,498 @@ +{ + "name": "testops-engineering", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "testops-engineering", + "version": "1.0.0", + "dependencies": { + "next": "^14.2.0", + "react": "^18.3.0", + "react-dom": "^18.3.0" + }, + "devDependencies": { + "@types/node": "^20", + "@types/react": "^18", + "@types/react-dom": "^18", + "typescript": "^5" + } + }, + "node_modules/@next/env": { + "version": "14.2.35", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.35.tgz", + "integrity": "sha512-DuhvCtj4t9Gwrx80dmz2F4t/zKQ4ktN8WrMwOuVzkJfBilwAwGr6v16M5eI8yCuZ63H9TTuEU09Iu2HqkzFPVQ==", + "license": "MIT" + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.33.tgz", + "integrity": "sha512-HqYnb6pxlsshoSTubdXKu15g3iivcbsMXg4bYpjL2iS/V6aQot+iyF4BUc2qA/J/n55YtvE4PHMKWBKGCF/+wA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.33.tgz", + "integrity": "sha512-8HGBeAE5rX3jzKvF593XTTFg3gxeU4f+UWnswa6JPhzaR6+zblO5+fjltJWIZc4aUalqTclvN2QtTC37LxvZAA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.33.tgz", + "integrity": "sha512-JXMBka6lNNmqbkvcTtaX8Gu5by9547bukHQvPoLe9VRBx1gHwzf5tdt4AaezW85HAB3pikcvyqBToRTDA4DeLw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.33.tgz", + "integrity": "sha512-Bm+QulsAItD/x6Ih8wGIMfRJy4G73tu1HJsrccPW6AfqdZd0Sfm5Imhgkgq2+kly065rYMnCOxTBvmvFY1BKfg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.33.tgz", + "integrity": "sha512-FnFn+ZBgsVMbGDsTqo8zsnRzydvsGV8vfiWwUo1LD8FTmPTdV+otGSWKc4LJec0oSexFnCYVO4hX8P8qQKaSlg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.33.tgz", + "integrity": "sha512-345tsIWMzoXaQndUTDv1qypDRiebFxGYx9pYkhwY4hBRaOLt8UGfiWKr9FSSHs25dFIf8ZqIFaPdy5MljdoawA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.33.tgz", + "integrity": "sha512-nscpt0G6UCTkrT2ppnJnFsYbPDQwmum4GNXYTeoTIdsmMydSKFz9Iny2jpaRupTb+Wl298+Rh82WKzt9LCcqSQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.33.tgz", + "integrity": "sha512-pc9LpGNKhJ0dXQhZ5QMmYxtARwwmWLpeocFmVG5Z0DzWq5Uf0izcI8tLc+qOpqxO1PWqZ5A7J1blrUIKrIFc7Q==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.33.tgz", + "integrity": "sha512-nOjfZMy8B94MdisuzZo9/57xuFVLHJaDj5e/xrduJp9CV2/HrfxTRH2fbyLe+K9QT41WBLUd4iXX3R7jBp0EUg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "license": "Apache-2.0" + }, + "node_modules/@swc/helpers": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", + "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==", + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3", + "tslib": "^2.4.0" + } + }, + "node_modules/@types/node": { + "version": "20.19.43", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.43.tgz", + "integrity": "sha512-6oYBAi5ikg4Pl+kGsoYtawUMBT2zZMCvPNF7pVLnHZfd1zf38DRiWn/gT01RYCdUqkv7Fhr+C9ot4/tb+2sVvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.31", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.31.tgz", + "integrity": "sha512-vfEqpXTvwT91yhmwdfouStN2hSKwTvyRs8qpLfADyrq/kxDw0hZM7Wk9Ug1FELj8hIby+S/+kQCSRFF32nv2Qw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001806", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz", + "integrity": "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/nanoid": { + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/next": { + "version": "14.2.35", + "resolved": "https://registry.npmjs.org/next/-/next-14.2.35.tgz", + "integrity": "sha512-KhYd2Hjt/O1/1aZVX3dCwGXM1QmOV4eNM2UTacK5gipDdPN/oHHK/4oVGy7X8GMfPMsUTUEmGlsy0EY1YGAkig==", + "license": "MIT", + "dependencies": { + "@next/env": "14.2.35", + "@swc/helpers": "0.5.5", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001579", + "graceful-fs": "^4.2.11", + "postcss": "8.4.31", + "styled-jsx": "5.1.1" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=18.17.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "14.2.33", + "@next/swc-darwin-x64": "14.2.33", + "@next/swc-linux-arm64-gnu": "14.2.33", + "@next/swc-linux-arm64-musl": "14.2.33", + "@next/swc-linux-x64-gnu": "14.2.33", + "@next/swc-linux-x64-musl": "14.2.33", + "@next/swc-win32-arm64-msvc": "14.2.33", + "@next/swc-win32-ia32-msvc": "14.2.33", + "@next/swc-win32-x64-msvc": "14.2.33" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.41.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", + "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..88d70e1 --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "name": "testops-engineering", + "version": "1.0.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start" + }, + "dependencies": { + "next": "^14.2.0", + "react": "^18.3.0", + "react-dom": "^18.3.0" + }, + "devDependencies": { + "@types/node": "^20", + "@types/react": "^18", + "@types/react-dom": "^18", + "typescript": "^5" + } +} diff --git a/public/logos/apple.svg b/public/logos/apple.svg new file mode 100644 index 0000000..82b0cdd --- /dev/null +++ b/public/logos/apple.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/public/logos/avid.png b/public/logos/avid.png new file mode 100644 index 0000000..47121d3 Binary files /dev/null and b/public/logos/avid.png differ diff --git a/public/logos/bankofamerica.svg b/public/logos/bankofamerica.svg new file mode 100644 index 0000000..f2630d5 --- /dev/null +++ b/public/logos/bankofamerica.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/logos/gap.svg b/public/logos/gap.svg new file mode 100644 index 0000000..1249ab4 --- /dev/null +++ b/public/logos/gap.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + diff --git a/public/logos/google.svg b/public/logos/google.svg new file mode 100644 index 0000000..3790851 --- /dev/null +++ b/public/logos/google.svg @@ -0,0 +1,2 @@ + + diff --git a/public/logos/hulu.svg b/public/logos/hulu.svg new file mode 100644 index 0000000..16476f7 --- /dev/null +++ b/public/logos/hulu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/logos/meta.svg b/public/logos/meta.svg new file mode 100644 index 0000000..fbfca7b --- /dev/null +++ b/public/logos/meta.svg @@ -0,0 +1,25 @@ + + +Logo of Meta Platforms -- Graphic created by Detmar Owen + + + + + + + + + + + + + + + + + diff --git a/public/logos/samsung.svg b/public/logos/samsung.svg new file mode 100644 index 0000000..627cbf2 --- /dev/null +++ b/public/logos/samsung.svg @@ -0,0 +1 @@ +Samsung \ No newline at end of file diff --git a/test_ops_logo.png b/public/test_ops_logo.png similarity index 100% rename from test_ops_logo.png rename to public/test_ops_logo.png diff --git a/testops_image.png b/public/testops_image.png similarity index 100% rename from testops_image.png rename to public/testops_image.png diff --git a/src/app/contact/page.tsx b/src/app/contact/page.tsx new file mode 100644 index 0000000..27f1a98 --- /dev/null +++ b/src/app/contact/page.tsx @@ -0,0 +1,107 @@ +import type { Metadata } from 'next' +import Nav from '@/components/Nav' + +export const metadata: Metadata = { + title: 'Contact — TestOps Engineering', + description: 'Contact TestOps Engineering for a scoped QA consulting quote.', + openGraph: { images: [{ url: '/testops_image.png' }] }, +} + +export default function Contact() { + return ( + <> +