Skip to content

Commit

Permalink
chore(crwa): add e2e tests for create-redwood-app (#9783)
Browse files Browse the repository at this point in the history
Similar to #9766, I was working
on ESM and started with CRWA since it's the easiest package, and there
really weren't any tests for it. (I think other tests, like the cypress
e2e test, use it, so I think we'd catch if it totally broke, but it's
not trivial to run that one locally for quick feedback.) This PR adds a
couple of e2e tests.

To run them locally:

```bash
# Build the framework
yarn build

# Tar CRWA
cd ./packages/create-redwood-app
yarn build:pack

# Create a test project to run the e2e tests on
PROJECT_PATH=$(yarn set-up-test-project)

# Run the jest test or a prompt test
PROJECT_PATH=$PROJECT_PATH yarn test:e2e
PROJECT_PATH=$PROJECT_PATH ./tests/e2e_prompts.sh
```

Some of the CRWA e2e tests use
[expect](https://core.tcl-lang.org/expect/index). I tried testing the
prompts using `zx`, Node's `child_process`, etc and writing to
`process.stdin`, but it never worked consistently and when it did it was
hacky. Expect more or less just worked. Those tests are limited to
Ubuntu, but better than the nothing we had before.

In making the ts-to-js script ESM, I was running it and it seems like
the JS template was a little out of date. So updated that as well.

A couple of other notes

- i got rid of the `.babelrc.js` file which was only there for jest. all
the tests are ESM now

- since i added a new script (setUpTestProject), i made a new scripts
directory and added tsToJS to it too

- one e2e test i don't have yet is for when the node version is lower or
higher. i couldn't seem to set it up with expect. will keep thinking
about how to test that one

- it's likely that the expect tests could be consolidated or just be
better in general

- every invocation of `yarn create-redwood-app` seems to be printing
some escape codes to `stderr`:

   ```js
   const p = await $`yarn create-redwood-app --help`
   expect(p.stderr).toMatchInlineSnapshot(`"�[?25l�[?25h"`)
  ```

- `yarn create-redwood-app --version` prints the banner and some escape
codes; both seem unnecessary:
  
   ```js
   const p = await $`yarn create-redwood-app --version`

   expect(p.exitCode).toEqual(0)
   expect(p.stdout).toMatchInlineSnapshot(`
     "------------------------------------------------------------------
                     🌲⚡️ Welcome to RedwoodJS! ⚡️🌲
     ------------------------------------------------------------------
     6.0.7
     �[?25l�[?25h"
   `)
  ```
  • Loading branch information
jtoar authored Dec 31, 2023
1 parent 2bba6f8 commit 35b858a
Show file tree
Hide file tree
Showing 15 changed files with 451 additions and 13 deletions.
76 changes: 76 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -701,3 +701,79 @@ jobs:

steps:
- run: echo "Skipped"

crwa:
needs: check

name: 🌲 Create Redwood App
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: ⬢ Enable Corepack
run: corepack enable

- name: ⬢ Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20

- name: 🐈 Set up yarn cache
uses: ./.github/actions/set-up-yarn-cache

- name: 🐈 Yarn install
run: yarn install --inline-builds
env:
GITHUB_TOKEN: ${{ github.token }}

- name: 🏗️ Build
run: yarn build

- name: Set up test project
run: |
yarn build:pack
PROJECT_PATH=$(yarn set-up-test-project)
echo "PROJECT_PATH=$PROJECT_PATH" >> $GITHUB_ENV
working-directory: ./packages/create-redwood-app
env:
YARN_ENABLE_IMMUTABLE_INSTALLS: false

- name: Set up git
run: |
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
- name: e2e test
run: yarn test e2e
working-directory: ./packages/create-redwood-app
env:
PROJECT_PATH: ${{ env.PROJECT_PATH }}

- name: Prompt tests
run: |
sudo apt-get update
sudo apt-get install expect
./tests/e2e_prompts.sh
sleep 1
./tests/e2e_prompts_git.sh
sleep 1
./tests/e2e_prompts_m.sh
sleep 1
./tests/e2e_prompts_ts.sh
sleep 1
./tests/e2e_prompts_overwrite.sh
working-directory: ./packages/create-redwood-app
env:
PROJECT_PATH: ${{ env.PROJECT_PATH }}

crwa-skip:
needs: detect-changes
if: needs.detect-changes.outputs.onlydocs == 'true'

name: 🌲 Create Redwood App
runs-on: ubuntu-latest

steps:
- run: echo "Skipped"
2 changes: 0 additions & 2 deletions packages/create-redwood-app/.babelrc.js

This file was deleted.

8 changes: 8 additions & 0 deletions packages/create-redwood-app/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/** @type {import('jest').Config} */
const config = {
testMatch: ['<rootDir>/tests/*.test.mjs'],
testPathIgnorePatterns: ['/node_modules/', '<rootDir>/templates/'],
transform: {},
}

module.exports = config
6 changes: 4 additions & 2 deletions packages/create-redwood-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
"build:pack": "yarn pack -o create-redwood-app.tgz",
"build:watch": "nodemon --watch src --ignore dist,template --exec \"yarn build\"",
"prepublishOnly": "NODE_ENV=production yarn build",
"test": "yarn run jest tests",
"ts-to-js": "yarn node ./tsToJS.mjs"
"set-up-test-project": "node ./scripts/setUpTestProject.mjs",
"test": "node --experimental-vm-modules $(yarn bin jest) templates",
"test:e2e": "node --experimental-vm-modules $(yarn bin jest) e2e",
"ts-to-js": "yarn node ./scripts/tsToJS.mjs"
},
"dependencies": {
"@opentelemetry/api": "1.7.0",
Expand Down
36 changes: 36 additions & 0 deletions packages/create-redwood-app/scripts/setUpTestProject.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* eslint-env node */

import { fileURLToPath } from 'node:url'

import Configstore from 'configstore'
import { cd, fs, os, path, $ } from 'zx'

const config = new Configstore('create-redwood-app')
let projectPath = config.get('projectPath')

const projectExists = projectPath && (await fs.pathExists(projectPath))

if (!projectExists) {
const [timestamp] = new Date().toISOString().replace(/-|:/g, '_').split('.')

projectPath = path.join(os.tmpdir(), `crwa_${timestamp}`)

await fs.ensureDir(projectPath)
await $`yarn --cwd ${projectPath} init -2`

config.set('projectPath', projectPath)
}

const packagePath = fileURLToPath(new URL('../', import.meta.url))
const tarball = 'create-redwood-app.tgz'

await fs.move(
path.join(packagePath, tarball),
path.join(projectPath, tarball),
{ overwrite: true }
)

cd(projectPath)
await $`yarn add ./${tarball}`

console.log(projectPath)
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import fs from 'fs-extra'
import { format } from 'prettier'

const [TS_TEMPLATE_FILEPATH, JS_TEMPLATE_FILEPATH] = [
new URL('./templates/ts', import.meta.url),
new URL('./templates/js', import.meta.url),
new URL('../templates/ts', import.meta.url),
new URL('../templates/js', import.meta.url),
].map(fileURLToPath)

const { default: prettierConfig } = await import(
new URL('./templates/ts/prettier.config.js', import.meta.url)
new URL('../templates/ts/prettier.config.js', import.meta.url)
)

// Handle node_modules, .yarn/install-state.gz.
Expand Down
3 changes: 0 additions & 3 deletions packages/create-redwood-app/templates/js/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,3 @@ indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true

[*.{md,html,mjml}]
trim_trailing_whitespace = false
3 changes: 2 additions & 1 deletion packages/create-redwood-app/templates/js/web/jsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
"../node_modules/@testing-library"
],
"types": [
"jest-dom",
"jest",
"jest-dom"
],
"jsx": "preserve"
},
Expand Down
108 changes: 108 additions & 0 deletions packages/create-redwood-app/tests/e2e.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#!/usr/bin/env node
/* eslint-env node */

import { cd, fs, $ } from 'zx'

const projectPath = await fs.realpath(process.env.PROJECT_PATH)

cd(projectPath)

describe('crwa', () => {
test('--help', async () => {
const p = await $`yarn create-redwood-app --help`

expect(p.exitCode).toEqual(0)
expect(p.stdout).toMatchInlineSnapshot(`
"------------------------------------------------------------------
🌲⚡️ Welcome to RedwoodJS! ⚡️🌲
------------------------------------------------------------------
Usage: create-redwood-app <project directory> [option]
Options:
--help Show help [boolean]
--typescript, --ts Generate a TypeScript project.
[boolean] [default: null]
--overwrite Create even if target directory isn't empty
[boolean] [default: false]
--telemetry Enables sending telemetry events for this create
command and all Redwood CLI commands
https://telemetry.redwoodjs.com
[boolean] [default: true]
--git-init, --git Initialize a git repository. [boolean] [default: null]
-m, --commit-message Commit message for the initial commit.
[string] [default: null]
-y, --yes Skip prompts and use defaults.
[boolean] [default: null]
--version Show version number [boolean]
Examples:
create-redwood-app newapp
[?25l[?25h"
`)
expect(p.stderr).toMatchInlineSnapshot(`"[?25l[?25h"`)
})

test('--version', async () => {
const p = await $`yarn create-redwood-app --version`

expect(p.exitCode).toEqual(0)
expect(p.stdout).toMatchInlineSnapshot(`
"------------------------------------------------------------------
🌲⚡️ Welcome to RedwoodJS! ⚡️🌲
------------------------------------------------------------------
6.0.7
[?25l[?25h"
`)
expect(p.stderr).toMatchInlineSnapshot(`"[?25l[?25h"`)
})

test('--yes, -y', async () => {
const p = await $`yarn create-redwood-app ./redwood-app --yes`

// await $`yarn create-redwood-app redwood-app -y`
// # `yarn pack` seems to ignore `.yarnrc.yml`
// # cp "$SCRIPT_DIR/templates/ts/.yarnrc.yml" "$CRWA_ESM_TESTING_DIR"

expect(p.exitCode).toEqual(0)
expect(p.stdout).toMatchInlineSnapshot(`
"------------------------------------------------------------------
🌲⚡️ Welcome to RedwoodJS! ⚡️🌲
------------------------------------------------------------------
[?25l⠋ Checking node and yarn compatibility
[?25h[?25l✔ Compatibility checks passed
[?25h✔ Creating your Redwood app in ./redwood-app based on command line argument
✔ Using TypeScript based on command line flag
✔ Will initialize a git repo based on command line flag
[?25l⠋ Creating project files
[?25h[?25l✔ Project files created
[?25h[?25l⠋ Initializing a git repo
[?25h[?25l✔ Initialized a git repo with commit message "Initial commit"
[?25h
Thanks for trying out Redwood!
⚡️ Get up and running fast with this Quick Start guide: https://redwoodjs.com/quick-start
Fire it up! 🚀
> cd redwood-app
> yarn install
> yarn rw dev
[?25l✔ Initialized a git repo with commit message "Initial commit"
[?25h"
`)
expect(p.stderr).toMatchInlineSnapshot(`"[?25l[?25h[?25l[?25h[?25l[?25h[?25l[?25h[?25l[?25h[?25l[?25h[?25l[?25h"`)

await fs.rm('./redwood-app', { recursive: true, force: true })
})

test.failing('fails on unknown options', async () => {
try {
await $`yarn create-redwood-app --unknown-options`.timeout(2500)
// Fail the test if the function didn't throw.
expect(true).toEqual(false)
} catch (p) {
expect(p.exitCode).toEqual(1)
}
})
})
42 changes: 42 additions & 0 deletions packages/create-redwood-app/tests/e2e_prompts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/expect

set projectPath $env(PROJECT_PATH)

if {$projectPath eq ""} {
puts "PROJECT_PATH is not set"
exit
}

cd $projectPath

set projectDirectory "redwood-app-prompt-test"

spawn yarn create-redwood-app

expect "Where would you like to create your Redwood app?"
send "$projectDirectory\n"

expect "Select your preferred language"
# TypeScript
send "\n"

expect "Do you want to initialize a git repo?"
# Yes
send "\n"

expect "Enter a commit message"
send "first\n"

expect eof
catch wait result
set exitStatus [lindex $result 3]

if {$exitStatus == 0} {
puts "Success"
exec rm -rf $projectDirectory
exit 0
} else {
puts "Error: The process failed with exit status $exitStatus"
exec rm -rf $projectDirectory
exit 1
}
38 changes: 38 additions & 0 deletions packages/create-redwood-app/tests/e2e_prompts_git.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/usr/bin/expect

set projectPath $env(PROJECT_PATH)

if {$projectPath eq ""} {
puts "PROJECT_PATH is not set"
exit
}

cd $projectPath

set projectDirectory "redwood-app-prompt-git-test"

spawn yarn create-redwood-app --git

expect "Where would you like to create your Redwood app?"
send "$projectDirectory\n"

expect "Select your preferred language"
# TypeScript
send "\n"

expect "Enter a commit message"
send "first\n"

expect eof
catch wait result
set exitStatus [lindex $result 3]

if {$exitStatus == 0} {
puts "Success"
exec rm -rf $projectDirectory
exit 0
} else {
puts "Error: The process failed with exit status $exitStatus"
exec rm -rf $projectDirectory
exit 1
}
Loading

0 comments on commit 35b858a

Please sign in to comment.