diff --git a/.eslintignore b/.eslintignore
index 2003cec41a0..a9f8b499220 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -3,3 +3,4 @@ node-tests/fixtures/**/*.js
/docs/
dist/
tmp/
+smoke-tests/
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 4912f5b752c..b2e1da40b0d 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -84,6 +84,29 @@ jobs:
BROWSERSTACK_ACCESS_KEY: o5LNEdygq1SP4L9kst4s
run: yarn test:browserstack
+ smoke-test:
+ name: Smoke tests (Full Ember Apps)
+ runs-on: ubuntu-latest
+ needs: [basic-test, lint]
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/setup-node@v2
+ with:
+ node-version: 12.x
+ cache: yarn
+ - name: install dependencies
+ run: yarn install --frozen-lockfile --non-interactive
+ - name: build
+ run: yarn ember build -prod
+ - name: test
+ # todo: potentially more apps? use matrix?
+ run: |
+ yarn link
+ cd smoke-tests/ember-test-app/
+ yarn
+ yarn link ember-source
+ yarn test
+
production-test:
name: Production (All Tests + Canary Features)
runs-on: ubuntu-latest
diff --git a/smoke-tests/ember-test-app/.editorconfig b/smoke-tests/ember-test-app/.editorconfig
new file mode 100644
index 00000000000..c35a002406b
--- /dev/null
+++ b/smoke-tests/ember-test-app/.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/smoke-tests/ember-test-app/.eslintignore b/smoke-tests/ember-test-app/.eslintignore
new file mode 100644
index 00000000000..701947ed3a6
--- /dev/null
+++ b/smoke-tests/ember-test-app/.eslintignore
@@ -0,0 +1,22 @@
+# unconventional js
+/blueprints/*/files/
+/vendor/
+
+# compiled output
+/dist/
+/tmp/
+
+# dependencies
+/bower_components/
+/node_modules/
+
+# misc
+/coverage/
+!.*
+.*/
+.eslintcache
+
+# ember-try
+/.node_modules.ember-try/
+/bower.json.ember-try
+/package.json.ember-try
diff --git a/smoke-tests/ember-test-app/.eslintrc.js b/smoke-tests/ember-test-app/.eslintrc.js
new file mode 100644
index 00000000000..41a1a43d828
--- /dev/null
+++ b/smoke-tests/ember-test-app/.eslintrc.js
@@ -0,0 +1,58 @@
+'use strict';
+
+module.exports = {
+ root: true,
+ parser: 'babel-eslint',
+ parserOptions: {
+ ecmaVersion: 2018,
+ sourceType: 'module',
+ ecmaFeatures: {
+ legacyDecorators: true,
+ },
+ },
+ plugins: ['ember'],
+ extends: [
+ 'eslint:recommended',
+ 'plugin:ember/recommended',
+ 'plugin:prettier/recommended',
+ ],
+ env: {
+ browser: true,
+ },
+ rules: {},
+ overrides: [
+ // node files
+ {
+ files: [
+ './.eslintrc.js',
+ './.prettierrc.js',
+ './.template-lintrc.js',
+ './ember-cli-build.js',
+ './testem.js',
+ './blueprints/*/index.js',
+ './config/**/*.js',
+ './lib/*/index.js',
+ './server/**/*.js',
+ ],
+ parserOptions: {
+ sourceType: 'script',
+ },
+ env: {
+ browser: false,
+ node: true,
+ },
+ plugins: ['node'],
+ extends: ['plugin:node/recommended'],
+ rules: {
+ // this can be removed once the following is fixed
+ // https://github.com/mysticatea/eslint-plugin-node/issues/77
+ 'node/no-unpublished-require': 'off',
+ },
+ },
+ {
+ // Test files:
+ files: ['tests/**/*-test.{js,ts}'],
+ extends: ['plugin:qunit/recommended'],
+ },
+ ],
+};
diff --git a/smoke-tests/ember-test-app/.gitignore b/smoke-tests/ember-test-app/.gitignore
new file mode 100644
index 00000000000..09a917f9c2c
--- /dev/null
+++ b/smoke-tests/ember-test-app/.gitignore
@@ -0,0 +1,29 @@
+# See https://help.github.com/ignore-files/ for more about ignoring files.
+# This smoke test ensures that a stable new'd app can run with latest ember-source
+# and not having the lock file will help us catch issues that maybe come from elsewhere.
+yarn.lock
+
+# compiled output
+/dist/
+/tmp/
+
+# dependencies
+/bower_components/
+/node_modules/
+
+# misc
+/.env*
+/.pnp*
+/.sass-cache
+/.eslintcache
+/connect.lock
+/coverage/
+/libpeerconnection.log
+/npm-debug.log*
+/testem.log
+/yarn-error.log
+
+# ember-try
+/.node_modules.ember-try/
+/bower.json.ember-try
+/package.json.ember-try
diff --git a/smoke-tests/ember-test-app/.prettierignore b/smoke-tests/ember-test-app/.prettierignore
new file mode 100644
index 00000000000..9221655522b
--- /dev/null
+++ b/smoke-tests/ember-test-app/.prettierignore
@@ -0,0 +1,21 @@
+# unconventional js
+/blueprints/*/files/
+/vendor/
+
+# compiled output
+/dist/
+/tmp/
+
+# dependencies
+/bower_components/
+/node_modules/
+
+# misc
+/coverage/
+!.*
+.eslintcache
+
+# ember-try
+/.node_modules.ember-try/
+/bower.json.ember-try
+/package.json.ember-try
diff --git a/smoke-tests/ember-test-app/.prettierrc.js b/smoke-tests/ember-test-app/.prettierrc.js
new file mode 100644
index 00000000000..534e6d35aab
--- /dev/null
+++ b/smoke-tests/ember-test-app/.prettierrc.js
@@ -0,0 +1,5 @@
+'use strict';
+
+module.exports = {
+ singleQuote: true,
+};
diff --git a/smoke-tests/ember-test-app/.template-lintrc.js b/smoke-tests/ember-test-app/.template-lintrc.js
new file mode 100644
index 00000000000..f35f61c7b3a
--- /dev/null
+++ b/smoke-tests/ember-test-app/.template-lintrc.js
@@ -0,0 +1,5 @@
+'use strict';
+
+module.exports = {
+ extends: 'recommended',
+};
diff --git a/smoke-tests/ember-test-app/app/app.js b/smoke-tests/ember-test-app/app/app.js
new file mode 100644
index 00000000000..b6e3fcb9768
--- /dev/null
+++ b/smoke-tests/ember-test-app/app/app.js
@@ -0,0 +1,12 @@
+import Application from '@ember/application';
+import Resolver from 'ember-resolver';
+import loadInitializers from 'ember-load-initializers';
+import config from 'ember-test-app/config/environment';
+
+export default class App extends Application {
+ modulePrefix = config.modulePrefix;
+ podModulePrefix = config.podModulePrefix;
+ Resolver = Resolver;
+}
+
+loadInitializers(App, config.modulePrefix);
diff --git a/smoke-tests/ember-test-app/app/components/.gitkeep b/smoke-tests/ember-test-app/app/components/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/smoke-tests/ember-test-app/app/controllers/.gitkeep b/smoke-tests/ember-test-app/app/controllers/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/smoke-tests/ember-test-app/app/helpers/.gitkeep b/smoke-tests/ember-test-app/app/helpers/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/smoke-tests/ember-test-app/app/index.html b/smoke-tests/ember-test-app/app/index.html
new file mode 100644
index 00000000000..846e9ed87e3
--- /dev/null
+++ b/smoke-tests/ember-test-app/app/index.html
@@ -0,0 +1,25 @@
+
+
+
+
+
+ EmberTestApp
+
+
+
+ {{content-for "head"}}
+
+
+
+
+ {{content-for "head-footer"}}
+
+
+ {{content-for "body"}}
+
+
+
+
+ {{content-for "body-footer"}}
+
+
diff --git a/smoke-tests/ember-test-app/app/models/.gitkeep b/smoke-tests/ember-test-app/app/models/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/smoke-tests/ember-test-app/app/router.js b/smoke-tests/ember-test-app/app/router.js
new file mode 100644
index 00000000000..aeffbcc03fb
--- /dev/null
+++ b/smoke-tests/ember-test-app/app/router.js
@@ -0,0 +1,9 @@
+import EmberRouter from '@ember/routing/router';
+import config from 'ember-test-app/config/environment';
+
+export default class Router extends EmberRouter {
+ location = config.locationType;
+ rootURL = config.rootURL;
+}
+
+Router.map(function () {});
diff --git a/smoke-tests/ember-test-app/app/routes/.gitkeep b/smoke-tests/ember-test-app/app/routes/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/smoke-tests/ember-test-app/app/styles/app.css b/smoke-tests/ember-test-app/app/styles/app.css
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/smoke-tests/ember-test-app/app/templates/application.hbs b/smoke-tests/ember-test-app/app/templates/application.hbs
new file mode 100644
index 00000000000..b0522933205
--- /dev/null
+++ b/smoke-tests/ember-test-app/app/templates/application.hbs
@@ -0,0 +1,7 @@
+{{page-title "EmberTestApp"}}
+
+{{!-- The following component displays Ember's default welcome message. --}}
+
+{{!-- Feel free to remove this! --}}
+
+{{outlet}}
\ No newline at end of file
diff --git a/smoke-tests/ember-test-app/config/ember-cli-update.json b/smoke-tests/ember-test-app/config/ember-cli-update.json
new file mode 100644
index 00000000000..b46cba5d89a
--- /dev/null
+++ b/smoke-tests/ember-test-app/config/ember-cli-update.json
@@ -0,0 +1,18 @@
+{
+ "schemaVersion": "1.0.0",
+ "packages": [
+ {
+ "name": "ember-cli",
+ "version": "3.28.4",
+ "blueprints": [
+ {
+ "name": "app",
+ "outputRepo": "https://github.com/ember-cli/ember-new-output",
+ "codemodsSource": "ember-app-codemods-manifest@1",
+ "isBaseBlueprint": true,
+ "options": []
+ }
+ ]
+ }
+ ]
+}
diff --git a/smoke-tests/ember-test-app/config/environment.js b/smoke-tests/ember-test-app/config/environment.js
new file mode 100644
index 00000000000..8f5d95a596f
--- /dev/null
+++ b/smoke-tests/ember-test-app/config/environment.js
@@ -0,0 +1,51 @@
+'use strict';
+
+module.exports = function (environment) {
+ let ENV = {
+ modulePrefix: 'ember-test-app',
+ environment,
+ rootURL: '/',
+ locationType: 'auto',
+ EmberENV: {
+ FEATURES: {
+ // Here you can enable experimental features on an ember canary build
+ // e.g. EMBER_NATIVE_DECORATOR_SUPPORT: true
+ },
+ EXTEND_PROTOTYPES: {
+ // Prevent Ember Data from overriding Date.parse.
+ Date: false,
+ },
+ },
+
+ 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/smoke-tests/ember-test-app/config/optional-features.json b/smoke-tests/ember-test-app/config/optional-features.json
new file mode 100644
index 00000000000..b26286e2ecd
--- /dev/null
+++ b/smoke-tests/ember-test-app/config/optional-features.json
@@ -0,0 +1,6 @@
+{
+ "application-template-wrapper": false,
+ "default-async-observers": true,
+ "jquery-integration": false,
+ "template-only-glimmer-components": true
+}
diff --git a/smoke-tests/ember-test-app/config/targets.js b/smoke-tests/ember-test-app/config/targets.js
new file mode 100644
index 00000000000..3cd797ab4fc
--- /dev/null
+++ b/smoke-tests/ember-test-app/config/targets.js
@@ -0,0 +1,26 @@
+'use strict';
+
+const browsers = [
+ 'last 1 Chrome versions',
+ 'last 1 Firefox versions',
+ 'last 1 Safari versions',
+];
+
+// Ember's browser support policy is changing, and IE11 support will end in
+// v4.0 onwards.
+//
+// See https://deprecations.emberjs.com/v3.x#toc_3-0-browser-support-policy
+//
+// If you need IE11 support on a version of Ember that still offers support
+// for it, uncomment the code block below.
+//
+// const isCI = Boolean(process.env.CI);
+// const isProduction = process.env.EMBER_ENV === 'production';
+//
+// if (isCI || isProduction) {
+// browsers.push('ie 11');
+// }
+
+module.exports = {
+ browsers,
+};
diff --git a/smoke-tests/ember-test-app/ember-cli-build.js b/smoke-tests/ember-test-app/ember-cli-build.js
new file mode 100644
index 00000000000..48e94e9e440
--- /dev/null
+++ b/smoke-tests/ember-test-app/ember-cli-build.js
@@ -0,0 +1,24 @@
+'use strict';
+
+const EmberApp = require('ember-cli/lib/broccoli/ember-app');
+
+module.exports = function (defaults) {
+ let app = new EmberApp(defaults, {
+ // Add options here
+ });
+
+ // Use `app.import` to add additional libraries to the generated
+ // output files.
+ //
+ // If you need to use different assets in different
+ // environments, specify an object as the first parameter. That
+ // object's keys should be the environment name and the values
+ // should be the asset to use in that environment.
+ //
+ // If the library that you are including contains AMD or ES6
+ // modules that you would like to import into your application
+ // please specify an object with the list of modules as keys
+ // along with the exports of each module as its value.
+
+ return app.toTree();
+};
diff --git a/smoke-tests/ember-test-app/package.json b/smoke-tests/ember-test-app/package.json
new file mode 100644
index 00000000000..3fe46b8a49d
--- /dev/null
+++ b/smoke-tests/ember-test-app/package.json
@@ -0,0 +1,71 @@
+{
+ "name": "ember-test-app",
+ "version": "0.0.0",
+ "private": true,
+ "description": "Small description for ember-test-app goes here",
+ "repository": "",
+ "license": "MIT",
+ "author": "",
+ "directories": {
+ "doc": "doc",
+ "test": "tests"
+ },
+ "scripts": {
+ "build": "ember build --environment=production",
+ "lint": "npm-run-all --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
+ "lint:fix": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*:fix",
+ "lint:hbs": "ember-template-lint .",
+ "lint:hbs:fix": "ember-template-lint . --fix",
+ "lint:js": "eslint . --cache",
+ "lint:js:fix": "eslint . --fix",
+ "start": "ember serve",
+ "test": "npm-run-all lint test:*",
+ "test:ember": "ember test"
+ },
+ "devDependencies": {
+ "@ember/optional-features": "^2.0.0",
+ "@ember/test-helpers": "^2.4.2",
+ "@glimmer/component": "^1.0.4",
+ "@glimmer/tracking": "^1.0.4",
+ "babel-eslint": "^10.1.0",
+ "broccoli-asset-rev": "^3.0.0",
+ "ember-auto-import": "^2.2.4",
+ "ember-cli": "~3.28.4",
+ "ember-cli-app-version": "^5.0.0",
+ "ember-cli-babel": "^7.26.6",
+ "ember-cli-dependency-checker": "^3.2.0",
+ "ember-cli-htmlbars": "^5.7.1",
+ "ember-cli-inject-live-reload": "^2.1.0",
+ "ember-cli-sri": "^2.1.1",
+ "ember-cli-terser": "^4.0.2",
+ "ember-data": "~3.28.0",
+ "ember-export-application-global": "^2.0.1",
+ "ember-fetch": "^8.1.1",
+ "ember-load-initializers": "^2.1.2",
+ "ember-maybe-import-regenerator": "^0.1.6",
+ "ember-page-title": "^6.2.2",
+ "ember-qunit": "^5.1.4",
+ "ember-resolver": "^8.0.2",
+ "ember-source": "~3.28.0",
+ "ember-template-lint": "^3.6.0",
+ "ember-welcome-page": "^4.0.0",
+ "eslint": "^7.32.0",
+ "eslint-config-prettier": "^8.3.0",
+ "eslint-plugin-ember": "^10.5.4",
+ "eslint-plugin-node": "^11.1.0",
+ "eslint-plugin-prettier": "^3.4.1",
+ "eslint-plugin-qunit": "^6.2.0",
+ "loader.js": "^4.7.0",
+ "npm-run-all": "^4.1.5",
+ "prettier": "^2.3.2",
+ "qunit": "^2.16.0",
+ "qunit-dom": "^1.6.0",
+ "webpack": "^5.65.0"
+ },
+ "engines": {
+ "node": "12.* || 14.* || >= 16"
+ },
+ "ember": {
+ "edition": "octane"
+ }
+}
diff --git a/smoke-tests/ember-test-app/public/robots.txt b/smoke-tests/ember-test-app/public/robots.txt
new file mode 100644
index 00000000000..f5916452e5f
--- /dev/null
+++ b/smoke-tests/ember-test-app/public/robots.txt
@@ -0,0 +1,3 @@
+# http://www.robotstxt.org
+User-agent: *
+Disallow:
diff --git a/smoke-tests/ember-test-app/testem.js b/smoke-tests/ember-test-app/testem.js
new file mode 100644
index 00000000000..ed2f37124ad
--- /dev/null
+++ b/smoke-tests/ember-test-app/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/smoke-tests/ember-test-app/tests/helpers/.gitkeep b/smoke-tests/ember-test-app/tests/helpers/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/smoke-tests/ember-test-app/tests/index.html b/smoke-tests/ember-test-app/tests/index.html
new file mode 100644
index 00000000000..87263eb9d1b
--- /dev/null
+++ b/smoke-tests/ember-test-app/tests/index.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+ EmberTestApp 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/smoke-tests/ember-test-app/tests/integration/.gitkeep b/smoke-tests/ember-test-app/tests/integration/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/smoke-tests/ember-test-app/tests/test-helper.js b/smoke-tests/ember-test-app/tests/test-helper.js
new file mode 100644
index 00000000000..2edd1d30e3c
--- /dev/null
+++ b/smoke-tests/ember-test-app/tests/test-helper.js
@@ -0,0 +1,12 @@
+import Application from 'ember-test-app/app';
+import config from 'ember-test-app/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/smoke-tests/ember-test-app/tests/unit/.gitkeep b/smoke-tests/ember-test-app/tests/unit/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/smoke-tests/ember-test-app/vendor/.gitkeep b/smoke-tests/ember-test-app/vendor/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d