diff --git a/frontend/.editorconfig b/frontend/.editorconfig new file mode 100644 index 0000000..c35a002 --- /dev/null +++ b/frontend/.editorconfig @@ -0,0 +1,19 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# editorconfig.org + +root = true + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space +indent_size = 2 + +[*.hbs] +insert_final_newline = false + +[*.{diff,md}] +trim_trailing_whitespace = false diff --git a/frontend/.ember-cli b/frontend/.ember-cli new file mode 100644 index 0000000..4defd28 --- /dev/null +++ b/frontend/.ember-cli @@ -0,0 +1,7 @@ +{ + /** + Setting `isTypeScriptProject` to true will force the blueprint generators to generate TypeScript + rather than JavaScript by default, when a TypeScript version of a given blueprint is available. + */ + "isTypeScriptProject": true +} diff --git a/frontend/.eslintignore b/frontend/.eslintignore new file mode 100644 index 0000000..768fab3 --- /dev/null +++ b/frontend/.eslintignore @@ -0,0 +1,14 @@ +# unconventional js +/blueprints/*/files/ + +# compiled output +/declarations/ +/dist/ + +# misc +/coverage/ +!.* +.*/ + +# ember-try +/.node_modules.ember-try/ diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js new file mode 100644 index 0000000..121ac75 --- /dev/null +++ b/frontend/.eslintrc.js @@ -0,0 +1,55 @@ +'use strict'; + +module.exports = { + root: true, + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaVersion: 'latest', + }, + plugins: ['ember', '@typescript-eslint'], + extends: [ + 'eslint:recommended', + 'plugin:ember/recommended', + 'plugin:prettier/recommended', + ], + env: { + browser: true, + }, + rules: {}, + overrides: [ + // ts files + { + files: ['**/*.ts'], + extends: [ + 'plugin:@typescript-eslint/eslint-recommended', + 'plugin:@typescript-eslint/recommended', + ], + rules: {}, + }, + // node files + { + files: [ + './.eslintrc.js', + './.prettierrc.js', + './.stylelintrc.js', + './.template-lintrc.js', + './ember-cli-build.js', + './testem.js', + './blueprints/*/index.js', + './config/**/*.js', + './lib/*/index.js', + './server/**/*.js', + ], + env: { + browser: false, + node: true, + }, + extends: ['plugin:n/recommended'], + }, + { + // test files + files: ['tests/**/*-test.{js,ts}'], + extends: ['plugin:qunit/recommended'], + }, + ], +}; diff --git a/frontend/.github/workflows/ci.yml b/frontend/.github/workflows/ci.yml new file mode 100644 index 0000000..8a43ff0 --- /dev/null +++ b/frontend/.github/workflows/ci.yml @@ -0,0 +1,47 @@ +name: CI + +on: + push: + branches: + - main + - master + pull_request: {} + +concurrency: + group: ci-${{ github.head_ref || github.ref }} + cancel-in-progress: true + +jobs: + lint: + name: "Lint" + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v3 + - name: Install Node + uses: actions/setup-node@v3 + with: + node-version: 18 + cache: npm + - name: Install Dependencies + run: npm ci + - name: Lint + run: npm run lint + + test: + name: "Test" + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v3 + - name: Install Node + uses: actions/setup-node@v3 + with: + node-version: 18 + cache: npm + - name: Install Dependencies + run: npm ci + - name: Run Tests + run: npm test diff --git a/frontend/.gitignore b/frontend/.gitignore new file mode 100644 index 0000000..71ad79d --- /dev/null +++ b/frontend/.gitignore @@ -0,0 +1,25 @@ +# compiled output +/dist/ +/declarations/ + +# dependencies +/node_modules/ + +# misc +/.env* +/.pnp* +/.eslintcache +/coverage/ +/npm-debug.log* +/testem.log +/yarn-error.log + +# ember-try +/.node_modules.ember-try/ +/npm-shrinkwrap.json.ember-try +/package.json.ember-try +/package-lock.json.ember-try +/yarn.lock.ember-try + +# broccoli-debug +/DEBUG/ diff --git a/frontend/.prettierignore b/frontend/.prettierignore new file mode 100644 index 0000000..9385391 --- /dev/null +++ b/frontend/.prettierignore @@ -0,0 +1,13 @@ +# unconventional js +/blueprints/*/files/ + +# compiled output +/dist/ + +# misc +/coverage/ +!.* +.*/ + +# ember-try +/.node_modules.ember-try/ diff --git a/frontend/.prettierrc.js b/frontend/.prettierrc.js new file mode 100644 index 0000000..e5f7b6d --- /dev/null +++ b/frontend/.prettierrc.js @@ -0,0 +1,12 @@ +'use strict'; + +module.exports = { + overrides: [ + { + files: '*.{js,ts}', + options: { + singleQuote: true, + }, + }, + ], +}; diff --git a/frontend/.stylelintignore b/frontend/.stylelintignore new file mode 100644 index 0000000..a0cf71c --- /dev/null +++ b/frontend/.stylelintignore @@ -0,0 +1,8 @@ +# unconventional files +/blueprints/*/files/ + +# compiled output +/dist/ + +# addons +/.node_modules.ember-try/ diff --git a/frontend/.stylelintrc.js b/frontend/.stylelintrc.js new file mode 100644 index 0000000..021c539 --- /dev/null +++ b/frontend/.stylelintrc.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = { + extends: ['stylelint-config-standard', 'stylelint-prettier/recommended'], +}; diff --git a/frontend/.template-lintrc.js b/frontend/.template-lintrc.js new file mode 100644 index 0000000..f35f61c --- /dev/null +++ b/frontend/.template-lintrc.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = { + extends: 'recommended', +}; diff --git a/frontend/.watchmanconfig b/frontend/.watchmanconfig new file mode 100644 index 0000000..f9c3d8f --- /dev/null +++ b/frontend/.watchmanconfig @@ -0,0 +1,3 @@ +{ + "ignore_dirs": ["dist"] +} diff --git a/frontend/README.md b/frontend/README.md new file mode 100644 index 0000000..c7d2872 --- /dev/null +++ b/frontend/README.md @@ -0,0 +1,56 @@ +# frontend + +This README outlines the details of collaborating on this Ember application. +A short introduction of this app could easily go here. + +## Prerequisites + +You will need the following things properly installed on your computer. + +- [Git](https://git-scm.com/) +- [Node.js](https://nodejs.org/) (with npm) +- [Ember CLI](https://cli.emberjs.com/release/) +- ~~Google Chrome~~ No, bad Ember. No Chrome. Use [Firefox](https://www.mozilla.org/en-US/firefox/new/) or [Ungoogled Chromium](https://github.com/ungoogled-software/ungoogled-chromium) instead + +## Installation + +- `git clone ` this repository +- `cd frontend` +- `npm install` + +## Running / Development + +- `npm run start` +- Visit your app at [http://localhost:4200](http://localhost:4200). +- Visit your tests at [http://localhost:4200/tests](http://localhost:4200/tests). + +### Code Generators + +Make use of the many generators for code, try `ember help generate` for more details + +### Running Tests + +- `npm run test` +- `npm run test:ember -- --server` + +### Linting + +- `npm run lint` +- `npm run lint:fix` + +### Building + +- `npm exec ember build` (development) +- `npm run build` (production) + +### Deploying + +Specify what it takes to deploy your app. + +## Further Reading / Useful Links + +- [ember.js](https://emberjs.com/) +- [ember-cli](https://cli.emberjs.com/release/) +- Development Browser Extensions + - [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi) + - [ember inspector for firefox](https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/) diff --git a/frontend/app/app.ts b/frontend/app/app.ts new file mode 100644 index 0000000..8da9f85 --- /dev/null +++ b/frontend/app/app.ts @@ -0,0 +1,12 @@ +import Application from '@ember/application'; +import Resolver from 'ember-resolver'; +import loadInitializers from 'ember-load-initializers'; +import config from 'frontend/config/environment'; + +export default class App extends Application { + modulePrefix = config.modulePrefix; + podModulePrefix = config.podModulePrefix; + Resolver = Resolver; +} + +loadInitializers(App, config.modulePrefix); diff --git a/frontend/app/components/.gitkeep b/frontend/app/components/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/frontend/app/config/environment.d.ts b/frontend/app/config/environment.d.ts new file mode 100644 index 0000000..609e6d6 --- /dev/null +++ b/frontend/app/config/environment.d.ts @@ -0,0 +1,14 @@ +/** + * Type declarations for + * import config from 'frontend/config/environment' + */ +declare const config: { + environment: string; + modulePrefix: string; + podModulePrefix: string; + locationType: 'history' | 'hash' | 'none'; + rootURL: string; + APP: Record; +}; + +export default config; diff --git a/frontend/app/controllers/.gitkeep b/frontend/app/controllers/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/frontend/app/helpers/.gitkeep b/frontend/app/helpers/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/frontend/app/index.html b/frontend/app/index.html new file mode 100644 index 0000000..69c8c0e --- /dev/null +++ b/frontend/app/index.html @@ -0,0 +1,24 @@ + + + + + Frontend + + + + {{content-for "head"}} + + + + + {{content-for "head-footer"}} + + + {{content-for "body"}} + + + + + {{content-for "body-footer"}} + + diff --git a/frontend/app/models/.gitkeep b/frontend/app/models/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/frontend/app/router.ts b/frontend/app/router.ts new file mode 100644 index 0000000..c9ad8c3 --- /dev/null +++ b/frontend/app/router.ts @@ -0,0 +1,11 @@ +import EmberRouter from '@ember/routing/router'; +import config from 'frontend/config/environment'; + +export default class Router extends EmberRouter { + location = config.locationType; + rootURL = config.rootURL; +} + +Router.map(function () { + // Add route declarations here +}); diff --git a/frontend/app/routes/.gitkeep b/frontend/app/routes/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/frontend/app/styles/app.css b/frontend/app/styles/app.css new file mode 100644 index 0000000..2763afa --- /dev/null +++ b/frontend/app/styles/app.css @@ -0,0 +1 @@ +/* Ember supports plain CSS out of the box. More info: https://cli.emberjs.com/release/advanced-use/stylesheets/ */ diff --git a/frontend/app/templates/application.hbs b/frontend/app/templates/application.hbs new file mode 100644 index 0000000..a13dd84 --- /dev/null +++ b/frontend/app/templates/application.hbs @@ -0,0 +1,7 @@ +{{page-title "Frontend"}} + +{{outlet}} + +{{! The following component displays Ember's default welcome message. }} + +{{! Feel free to remove this! }} \ No newline at end of file diff --git a/frontend/biome.json b/frontend/biome.json new file mode 100644 index 0000000..eb817cf --- /dev/null +++ b/frontend/biome.json @@ -0,0 +1,156 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.9.3/schema.json", + "vcs": { "enabled": false, "clientKind": "git", "useIgnoreFile": false }, + "files": { "ignoreUnknown": false, "ignore": [] }, + "formatter": { + "enabled": true, + "useEditorconfig": true, + "formatWithErrors": false, + "indentStyle": "space", + "indentWidth": 2, + "lineEnding": "lf", + "lineWidth": 80, + "attributePosition": "auto", + "bracketSpacing": true, + "ignore": [ + "./blueprints/*/files/", + "./dist/", + "./coverage/", + "**/.*/", + "./.node_modules.ember-try/" + ] + }, + "organizeImports": { "enabled": true }, + "linter": { + "enabled": true, + "rules": { + "recommended": false, + "complexity": { + "noExtraBooleanCast": "error", + "noMultipleSpacesInRegularExpressionLiterals": "error", + "noUselessCatch": "error", + "noWith": "error", + "useArrowFunction": "off" + }, + "correctness": { + "noConstAssign": "error", + "noConstantCondition": "error", + "noEmptyCharacterClassInRegex": "error", + "noEmptyPattern": "error", + "noGlobalObjectCalls": "error", + "noInnerDeclarations": "error", + "noInvalidConstructorSuper": "error", + "noNewSymbol": "error", + "noNonoctalDecimalEscape": "error", + "noPrecisionLoss": "error", + "noSelfAssign": "error", + "noSetterReturn": "error", + "noSwitchDeclarations": "error", + "noUndeclaredVariables": "error", + "noUnreachable": "error", + "noUnreachableSuper": "error", + "noUnsafeFinally": "error", + "noUnsafeOptionalChaining": "error", + "noUnusedLabels": "error", + "noUnusedVariables": "error", + "useIsNan": "error", + "useValidForDirection": "error", + "useYield": "error" + }, + "style": { "useBlockStatements": "off" }, + "suspicious": { + "noAssignInExpressions": "error", + "noAsyncPromiseExecutor": "error", + "noCatchAssign": "error", + "noClassAssign": "error", + "noCompareNegZero": "error", + "noControlCharactersInRegex": "error", + "noDebugger": "error", + "noDuplicateCase": "error", + "noDuplicateClassMembers": "error", + "noDuplicateObjectKeys": "error", + "noDuplicateParameters": "error", + "noEmptyBlockStatements": "error", + "noFallthroughSwitchClause": "error", + "noFunctionAssign": "error", + "noGlobalAssign": "error", + "noImportAssign": "error", + "noMisleadingCharacterClass": "error", + "noPrototypeBuiltins": "error", + "noRedeclare": "error", + "noShadowRestrictedNames": "error", + "noSparseArray": "error", + "noUnsafeNegation": "error", + "useGetterReturn": "error", + "useValidTypeof": "error" + } + }, + "ignore": [ + "./blueprints/*/files/", + "./declarations/", + "./dist/", + "./coverage/", + "**/.*/", + "./.node_modules.ember-try/" + ] + }, + "javascript": { + "formatter": { + "jsxQuoteStyle": "double", + "quoteProperties": "asNeeded", + "trailingCommas": "all", + "semicolons": "asNeeded", + "arrowParentheses": "always", + "bracketSameLine": false, + "quoteStyle": "single", + "attributePosition": "auto", + "bracketSpacing": true + } + }, + "overrides": [ + { "include": ["**/*.ts"] }, + { + "include": [ + "./.eslintrc.js", + "./.prettierrc.js", + "./.stylelintrc.js", + "./.template-lintrc.js", + "./ember-cli-build.js", + "./testem.js", + "./blueprints/*/index.js", + "./config/**/*.js", + "./lib/*/index.js", + "./server/**/*.js" + ] + }, + { "include": ["tests/**/*-test.{js,ts}"] }, + { + "include": ["**/*.gjs", "**/*.gts"], + "javascript": { "globals": ["__GLIMMER_TEMPLATE"] } + }, + { "include": ["**/*.ts"] }, + { + "include": [ + "./.eslintrc.js", + "./.prettierrc.js", + "./.stylelintrc.js", + "./.template-lintrc.js", + "./ember-cli-build.js", + "./testem.js", + "./blueprints/*/index.js", + "./config/**/*.js", + "./lib/*/index.js", + "./server/**/*.js" + ] + }, + { "include": ["tests/**/*-test.{js,ts}"] }, + { + "include": ["**/*.gjs", "**/*.gts"], + "javascript": { "globals": ["__GLIMMER_TEMPLATE"] } + }, + { + "include": ["*.{js,ts}"], + "javascript": { "formatter": { "quoteStyle": "single" } } + } + ] +} diff --git a/frontend/config/ember-cli-update.json b/frontend/config/ember-cli-update.json new file mode 100644 index 0000000..d45ddd1 --- /dev/null +++ b/frontend/config/ember-cli-update.json @@ -0,0 +1,22 @@ +{ + "schemaVersion": "1.0.0", + "packages": [ + { + "name": "ember-cli", + "version": "6.0.1", + "blueprints": [ + { + "name": "app", + "outputRepo": "https://github.com/ember-cli/ember-new-output", + "codemodsSource": "ember-app-codemods-manifest@1", + "isBaseBlueprint": true, + "options": [ + "--embroider", + "--ci-provider=github", + "--typescript" + ] + } + ] + } + ] +} diff --git a/frontend/config/environment.js b/frontend/config/environment.js new file mode 100644 index 0000000..e979f0a --- /dev/null +++ b/frontend/config/environment.js @@ -0,0 +1,48 @@ +'use strict'; + +module.exports = function (environment) { + const ENV = { + modulePrefix: 'frontend', + environment, + rootURL: '/', + locationType: 'history', + EmberENV: { + EXTEND_PROTOTYPES: false, + FEATURES: { + // Here you can enable experimental features on an ember canary build + // e.g. EMBER_NATIVE_DECORATOR_SUPPORT: true + }, + }, + + APP: { + // Here you can pass flags/options to your application instance + // when it is created + }, + }; + + if (environment === 'development') { + // ENV.APP.LOG_RESOLVER = true; + // ENV.APP.LOG_ACTIVE_GENERATION = true; + // ENV.APP.LOG_TRANSITIONS = true; + // ENV.APP.LOG_TRANSITIONS_INTERNAL = true; + // ENV.APP.LOG_VIEW_LOOKUPS = true; + } + + if (environment === 'test') { + // Testem prefers this... + ENV.locationType = 'none'; + + // keep test console output quieter + ENV.APP.LOG_ACTIVE_GENERATION = false; + ENV.APP.LOG_VIEW_LOOKUPS = false; + + ENV.APP.rootElement = '#ember-testing'; + ENV.APP.autoboot = false; + } + + if (environment === 'production') { + // here you can enable a production-specific feature + } + + return ENV; +}; diff --git a/frontend/config/optional-features.json b/frontend/config/optional-features.json new file mode 100644 index 0000000..5329dd9 --- /dev/null +++ b/frontend/config/optional-features.json @@ -0,0 +1,7 @@ +{ + "application-template-wrapper": false, + "default-async-observers": true, + "jquery-integration": false, + "template-only-glimmer-components": true, + "no-implicit-route-model": true +} diff --git a/frontend/config/targets.js b/frontend/config/targets.js new file mode 100644 index 0000000..1e48e05 --- /dev/null +++ b/frontend/config/targets.js @@ -0,0 +1,11 @@ +'use strict'; + +const browsers = [ + 'last 1 Chrome versions', + 'last 1 Firefox versions', + 'last 1 Safari versions', +]; + +module.exports = { + browsers, +}; diff --git a/frontend/ember-cli-build.js b/frontend/ember-cli-build.js new file mode 100644 index 0000000..069e701 --- /dev/null +++ b/frontend/ember-cli-build.js @@ -0,0 +1,26 @@ +'use strict'; + +const EmberApp = require('ember-cli/lib/broccoli/ember-app'); + +module.exports = function (defaults) { + const app = new EmberApp(defaults, { + 'ember-cli-babel': { enableTypeScriptTransform: true }, + + // Add options here + }); + + const { Webpack } = require('@embroider/webpack'); + return require('@embroider/compat').compatBuild(app, Webpack, { + staticAddonTestSupportTrees: true, + staticAddonTrees: true, + staticHelpers: true, + staticModifiers: true, + staticComponents: true, + staticEmberSource: true, + skipBabel: [ + { + package: 'qunit', + }, + ], + }); +}; diff --git a/frontend/package.json b/frontend/package.json new file mode 100644 index 0000000..ea76cd7 --- /dev/null +++ b/frontend/package.json @@ -0,0 +1,99 @@ +{ + "name": "frontend", + "version": "0.0.0", + "private": true, + "description": "Small description for frontend goes here", + "repository": "", + "license": "MIT", + "author": "", + "directories": { + "doc": "doc", + "test": "tests" + }, + "scripts": { + "build": "ember build --environment=production", + "lint": "concurrently \"npm:lint:*(!fix)\" --names \"lint:\"", + "lint:css": "stylelint \"**/*.css\"", + "lint:css:fix": "concurrently \"npm:lint:css -- --fix\"", + "lint:fix": "concurrently \"npm:lint:*:fix\" --names \"fix:\"", + "lint:hbs": "ember-template-lint .", + "lint:hbs:fix": "ember-template-lint . --fix", + "lint:js": "eslint . --cache", + "lint:js:fix": "eslint . --fix", + "lint:types": "tsc --noEmit", + "start": "ember serve", + "test": "concurrently \"npm:lint\" \"npm:test:*\" --names \"lint,test:\"", + "test:ember": "ember test" + }, + "devDependencies": { + "@babel/core": "^7.26.0", + "@ember-data/adapter": "~5.4.0-beta.12", + "@ember-data/graph": "~5.4.0-beta.12", + "@ember-data/json-api": "~5.4.0-beta.12", + "@ember-data/legacy-compat": "~5.4.0-beta.12", + "@ember-data/model": "~5.4.0-beta.12", + "@ember-data/request": "~5.4.0-beta.12", + "@ember-data/request-utils": "~5.4.0-beta.12", + "@ember-data/serializer": "~5.4.0-beta.12", + "@ember-data/store": "~5.4.0-beta.12", + "@ember-data/tracking": "~5.4.0-beta.12", + "@ember/optional-features": "^2.2.0", + "@ember/string": "^4.0.0", + "@ember/test-helpers": "^4.0.4", + "@embroider/compat": "^3.7.0", + "@embroider/core": "^3.4.19", + "@embroider/webpack": "^4.0.8", + "@glimmer/component": "^1.1.2", + "@glimmer/tracking": "^1.1.2", + "@glint/environment-ember-loose": "^1.5.0", + "@glint/template": "^1.5.0", + "@tsconfig/ember": "^3.0.8", + "@types/qunit": "^2.19.12", + "@types/rsvp": "^4.0.9", + "@typescript-eslint/eslint-plugin": "^7.18.0", + "@typescript-eslint/parser": "^7.18.0", + "@warp-drive/core-types": "~0.0.0-beta.12", + "broccoli-asset-rev": "^3.0.0", + "concurrently": "^8.2.2", + "ember-auto-import": "^2.10.0", + "ember-cli": "~6.0.1", + "ember-cli-app-version": "^7.0.0", + "ember-cli-babel": "^8.2.0", + "ember-cli-clean-css": "^3.0.0", + "ember-cli-dependency-checker": "^3.3.2", + "ember-cli-htmlbars": "^6.3.0", + "ember-cli-inject-live-reload": "^2.1.0", + "ember-data": "~5.3.9", + "ember-fetch": "^8.1.2", + "ember-load-initializers": "^2.1.2", + "ember-modifier": "^4.2.0", + "ember-page-title": "^8.2.3", + "ember-qunit": "^8.1.1", + "ember-resolver": "^12.0.1", + "ember-source": "~6.0.0", + "ember-template-lint": "^6.0.0", + "ember-welcome-page": "^7.0.2", + "eslint": "^8.57.1", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-ember": "^12.3.1", + "eslint-plugin-n": "^16.6.2", + "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-qunit": "^8.1.2", + "loader.js": "^4.7.0", + "prettier": "^3.3.3", + "qunit": "^2.22.0", + "qunit-dom": "^3.3.0", + "stylelint": "^15.11.0", + "stylelint-config-standard": "^34.0.0", + "stylelint-prettier": "^4.1.0", + "tracked-built-ins": "^3.3.0", + "typescript": "^5.6.3", + "webpack": "^5.96.1" + }, + "engines": { + "node": ">= 18" + }, + "ember": { + "edition": "octane" + } +} diff --git a/frontend/public/robots.txt b/frontend/public/robots.txt new file mode 100644 index 0000000..f591645 --- /dev/null +++ b/frontend/public/robots.txt @@ -0,0 +1,3 @@ +# http://www.robotstxt.org +User-agent: * +Disallow: diff --git a/frontend/testem.js b/frontend/testem.js new file mode 100644 index 0000000..ed2f371 --- /dev/null +++ b/frontend/testem.js @@ -0,0 +1,23 @@ +'use strict'; + +module.exports = { + test_page: 'tests/index.html?hidepassed', + disable_watching: true, + launch_in_ci: ['Chrome'], + launch_in_dev: ['Chrome'], + browser_start_timeout: 120, + browser_args: { + Chrome: { + ci: [ + // --no-sandbox is needed when running Chrome inside a container + process.env.CI ? '--no-sandbox' : null, + '--headless', + '--disable-dev-shm-usage', + '--disable-software-rasterizer', + '--mute-audio', + '--remote-debugging-port=0', + '--window-size=1440,900', + ].filter(Boolean), + }, + }, +}; diff --git a/frontend/tests/helpers/index.ts b/frontend/tests/helpers/index.ts new file mode 100644 index 0000000..e190f56 --- /dev/null +++ b/frontend/tests/helpers/index.ts @@ -0,0 +1,43 @@ +import { + setupApplicationTest as upstreamSetupApplicationTest, + setupRenderingTest as upstreamSetupRenderingTest, + setupTest as upstreamSetupTest, + type SetupTestOptions, +} from 'ember-qunit'; + +// This file exists to provide wrappers around ember-qunit's +// test setup functions. This way, you can easily extend the setup that is +// needed per test type. + +function setupApplicationTest(hooks: NestedHooks, options?: SetupTestOptions) { + upstreamSetupApplicationTest(hooks, options); + + // Additional setup for application tests can be done here. + // + // For example, if you need an authenticated session for each + // application test, you could do: + // + // hooks.beforeEach(async function () { + // await authenticateSession(); // ember-simple-auth + // }); + // + // This is also a good place to call test setup functions coming + // from other addons: + // + // setupIntl(hooks, 'en-us'); // ember-intl + // setupMirage(hooks); // ember-cli-mirage +} + +function setupRenderingTest(hooks: NestedHooks, options?: SetupTestOptions) { + upstreamSetupRenderingTest(hooks, options); + + // Additional setup for rendering tests can be done here. +} + +function setupTest(hooks: NestedHooks, options?: SetupTestOptions) { + upstreamSetupTest(hooks, options); + + // Additional setup for unit tests can be done here. +} + +export { setupApplicationTest, setupRenderingTest, setupTest }; diff --git a/frontend/tests/index.html b/frontend/tests/index.html new file mode 100644 index 0000000..501289e --- /dev/null +++ b/frontend/tests/index.html @@ -0,0 +1,39 @@ + + + + + Frontend Tests + + + + {{content-for "head"}} + {{content-for "test-head"}} + + + + + + {{content-for "head-footer"}} + {{content-for "test-head-footer"}} + + + {{content-for "body"}} + {{content-for "test-body"}} + +
+
+
+
+
+
+ + + + + + + + {{content-for "body-footer"}} + {{content-for "test-body-footer"}} + + diff --git a/frontend/tests/integration/.gitkeep b/frontend/tests/integration/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/frontend/tests/test-helper.ts b/frontend/tests/test-helper.ts new file mode 100644 index 0000000..b5cc6d9 --- /dev/null +++ b/frontend/tests/test-helper.ts @@ -0,0 +1,12 @@ +import Application from 'frontend/app'; +import config from 'frontend/config/environment'; +import * as QUnit from 'qunit'; +import { setApplication } from '@ember/test-helpers'; +import { setup } from 'qunit-dom'; +import { start } from 'ember-qunit'; + +setApplication(Application.create(config.APP)); + +setup(QUnit.assert); + +start(); diff --git a/frontend/tests/unit/.gitkeep b/frontend/tests/unit/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json new file mode 100644 index 0000000..396fd47 --- /dev/null +++ b/frontend/tsconfig.json @@ -0,0 +1,29 @@ +{ + "extends": "@tsconfig/ember/tsconfig.json", + "compilerOptions": { + // The combination of `baseUrl` with `paths` allows Ember's classic package + // layout, which is not resolvable with the Node resolution algorithm, to + // work with TypeScript. + "baseUrl": ".", + "paths": { + "frontend/tests/*": ["tests/*"], + "frontend/*": ["app/*"], + "*": ["types/*"] + }, + "types": [ + "ember-source/types", + "./node_modules/ember-data/unstable-preview-types", + "./node_modules/@ember-data/store/unstable-preview-types", + "./node_modules/@ember-data/adapter/unstable-preview-types", + "./node_modules/@ember-data/graph/unstable-preview-types", + "./node_modules/@ember-data/json-api/unstable-preview-types", + "./node_modules/@ember-data/legacy-compat/unstable-preview-types", + "./node_modules/@ember-data/request/unstable-preview-types", + "./node_modules/@ember-data/request-utils/unstable-preview-types", + "./node_modules/@ember-data/model/unstable-preview-types", + "./node_modules/@ember-data/serializer/unstable-preview-types", + "./node_modules/@ember-data/tracking/unstable-preview-types", + "./node_modules/@warp-drive/core-types/unstable-preview-types" + ] + } +} diff --git a/frontend/types/global.d.ts b/frontend/types/global.d.ts new file mode 100644 index 0000000..2c531e2 --- /dev/null +++ b/frontend/types/global.d.ts @@ -0,0 +1 @@ +import '@glint/environment-ember-loose'; diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..12894b2 --- /dev/null +++ b/go.mod @@ -0,0 +1,10 @@ +module git.mstar.dev/mstar/go-ember-template + +go 1.23.3 + +require ( + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/rs/zerolog v1.33.0 // indirect + golang.org/x/sys v0.12.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..98afda4 --- /dev/null +++ b/go.sum @@ -0,0 +1,15 @@ +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= +github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=