nuxt / typescript

TypeScript Support for Nuxt 2
https://typescript.nuxtjs.org
MIT License
569 stars 124 forks source link

Add an example of working with ava #293

Open JakubKoralewski opened 4 years ago

JakubKoralewski commented 4 years ago

Is your feature request related to a problem? Please describe. I can't get Ava to work with Typescript and Nuxt. It's very weird, but my project works npm run dev is all fine, but then if I type npm run test with ava not only do I get an error in the test about my types, but also when I run npm run dev from this point on it stops working up until I remove package-lock.json and node_modules!

I believe (before I migrated to 2.11) on 2.0.0 I had a different problem but not this one though.

My ava configuration that I got from somewhere a year ago:

    "ava": {
        "compileEnhancements": false,
        "extensions": [
            "ts"
        ],
        "extensions": ["ts"],
        "files": [
            "**/*.test.ts"
        ],
        "sources": [
            "src/**/*"
        ],
        "require": [
            "esm",
            "ts-node/register"
        ],
        "verbose": true
    },

Describe the solution you'd like An example how to work with testing in Typescript on Nuxt 2.9+

kevinmarrec commented 4 years ago

@JakubKoralewski Is there any repository with project and basic ava tests you could share ?

JakubKoralewski commented 4 years ago

Sure. This is a site I'm working on. I use ava only here since I couldn't get it to integrate with Nuxt/Vue :/ So it's just ava with Typescript but no Nuxt involved. It uses ava v2. I'm now trying to migrate to v3.

EDIT1: And also this is a test that I can't get to work:

import test from "ava";
import { Nuxt, Builder } from "nuxt";
import { Configuration } from "@nuxt/types";
import { resolve } from "path";
// import vars from "~/assets/scss/_variables.scss";
// import getPort from "get-port";
// import variables from "@/components/Contact/Contact";
// We keep a reference to Nuxt so we can close
// the server at the end of the test

// Init Nuxt.js and start listening on localhost:4000
test.before("Init Nuxt.js", async t => {
    const rootDir = resolve(__dirname, "..");
    let config: Configuration = {};
    try {
        config = require(resolve(rootDir, "nuxt.config.ts")).default;
    } catch (e) {
        console.log("Config error: ", e);
    }
    config.rootDir = rootDir; // project folder
    config.dev = false; // production build
    config.mode = "universal"; // Isomorphic application
    config._typescript = { build: true };
    const nuxt = new Nuxt(config);
    t.context.nuxt = nuxt;
    console.log("Awaiting nuxt ready");
    // await nuxt.ready();
    await new Builder(nuxt).build();
    nuxt.listen(6969, "localhost");
});

// Example of testing only generated html
test("Route / exits and render HTML", async t => {
    const { nuxt } = t.context;
    const context = {};
    const { html }: { html: string } = await nuxt.renderRoute("/", context);
    t.true(html.includes("mireks"));
});

// Example of testing via DOM checking
test("Route / exists and renders HTML with CSS applied", async t => {
    console.log("Rendering window");
    // console.log("nuxt.server: ", nuxt.server);
    const loadedCallback = (x, y, z) => {
        console.log("Loaded callback", x, y, z);
    };

    const window: Window = await nuxt.renderAndGetWindow("/", {}, {loadedCallback, loadingTimeout: 50000});
    const main: HTMLElement = window.document.querySelector(
        "main"
    ) as HTMLElement;
    t.not(main, null);
    t.true(main.classList.contains("global-padding"));
    t.is(main.style.paddingLeft, vars.globalPaddingHorizontal);
    t.is(main.style.paddingRight, vars.globalPaddingHorizontal);
});

// Close the Nuxt server
test.after("Closing server", t => {
    t.context.nuxt.close();
});

It doesn't want to wait for Nuxt to finish building the webpage and throws a timeout error :/

JakubKoralewski commented 4 years ago

I was able to make it work. Changes in this PR.

vintprox commented 4 years ago

t.context is of unknown type, thus adding property to it creates error Object is of type 'unknown'. To negotiate it, I had to store nuxt instance in the scope of script.

Also, nuxt contains no typings for Nuxt and Builder, had to shim them to any as people show in #44. Indeed, what a weird sight.

Plus, E2E instructions are not being clear about running Nuxt with its plugins for testing components in isolation.

vintprox commented 4 years ago

Found out that Ava is getting contribution to test.resource that can be used for Nuxt.js server before running any test (all or few, you decide), as well as correctly disposing of it. https://github.com/avajs/ava/issues/1366

/**
 * Proof-of-concept Ava test.resource for setting up Nuxt.js server before running any tests
 * @see https://github.com/avajs/ava/pull/2478
 */

import { resolve } from 'path'
import test from 'ava'
import { Nuxt, Builder } from 'nuxt'
import { Configuration } from '@nuxt/types'

test.resource('Set up Nuxt.js test server', async () => {
  const rootDir = resolve(__dirname, '..')
  let config: Configuration = {}
  try {
    config = require(resolve(rootDir, 'nuxt.config.js'))
  } catch (e) {}
  config.rootDir = rootDir
  config.dev = false
  const nuxt = new Nuxt(config)
  await new Builder(nuxt).build()
  nuxt.listen(3030, 'localhost')

  return async () => {
    nuxt.close()
  }
}
kevinmarrec commented 4 years ago

Anyone wanting to create a PR with minimal ava + TypeScript setup ? :)