How to start Aurelia site before Cypress testing?

#1

I need to know How to run “start” command in Aurelia project in the background and run cypress for e2e testing.

image

I tried these commands but does not work.

npm run start && ./node_modules/.bin/cypress run

npm run start & ./node_modules/.bin/cypress run

npm-run-all --serial \"start\" \"test:e2e\"

"concurrently \"start\" \"test:e2e\""

It seems that the start command is not allowed to run cypress command.

I want to run the site before e2e testing in automatic mode (not manually in separated consoles).

1 Like
#2

We had this issue with one of our projects. We ended up using gulp to orchestrate the running of the app as well as running the Cypress tests. That way, we are able to tear down the app after the Cypress tests.

Let me see if I’m able to post some snippets for you.

2 Likes
#3

I think all of Aurelia CLI scenarios work on Gulp !!! Please share an example or snippet code.

Thanks.

1 Like
#4

Here you go. I do hope you find it useful!

3 Likes
#5

Thanks @rowellx68

We added your snippet code as au command in this repository.

The command to use is au cy.
The project is based on the great @huochunpeng plugin system in here.
But we have a problem, seems the site does not start well on port 8080.

May I ask you to check this repository?

1 Like
#6

Here’s the image :

1 Like
#7

Shouldn’t this be ${PORT}?

2 Likes
#8

@khuongduybui

You right It should be. I fixed it but It is not the solution :frowning:

1 Like
#9

I have found the difference as to why it worked with our project.

server = spawn(process.argv[0], ["server.js"], {
    detached: true,
    stdio: "ignore"
});

The snippet above is what we have within the startServer method. It turns out process.argv[0] is node and in turn that runs server.js serving our compiled application.

I tried replacing the params to "npm.cmd", ["start"]...and that seems to have done it, but it wasn’t able to teardown the server after the test has run.

2 Likes
#10

@rowellx68

You rock!

but it wasn’t able to teardown the server after the test has run.

It is too bad for CI/CD scenarios, Is it possible to find process id and kill it?

I find a solution, however, It is not good but better than nothing!

function killServer(done) {
  server.kill();
  done();

  // Kill all node.exe processes
  const killall = exec('taskkill /f /im node.exe', (error, stdout, stderr) => {
    console.log(`stdout: ${stdout}`);
    console.log(`stderr: ${stderr}`);
    if (error !== null) {
      console.log(`exec error: ${error}`);
    }
  });
}

Another question: Is it possible to disable opening browser (headless)?

1 Like
#11

There were multiple ways which the project could be ran, one uses PORT and the other on 8080, I was checking with both and to o avail. anyway, thanks for mentioning :pray:

1 Like
#12

spawn should include a bunch of properties. You might be able get the process id there, the issue however is that using npm.cmd spawns other processes… those you won’t be able to get the process id.

I will have a look at our server.js file when I get time and get back to you.

As for running Cypress headless, you can look inside gulp-cypress.ts and replace the browser with electron. Currently, that’s the only way to run a headless browser.

3 Likes
#13

In the new CLI I just import run method from the run.ts script and call it, works fine!

cypress.ts

import * as cypress from 'cypress';
import * as config from '../../cypress.config';
import { CLIOptions } from 'aurelia-cli';

import * as run from './run';

export default (cb) => {

  let hasRunProject  = process.argv.find(x=>x === "--start") || false;
  if(hasRunProject){
    run.default();
  }

  if (CLIOptions.hasFlag('run')) {
    cypress
      .run(config)
      .then(results => (results.totalFailed === 0 ? cb() : cb('Run failed!')))
      .catch(cb);
  } else {
    cypress.open(config);
  }
};

package.json/scripts

,
  "scripts": {
    "build": "au build",
    "start": "au run",
    "test": "au test",
    "e2e": "au cypress",
    "e2e:headless" : "au cypress --run"
  },

an example:

au cypress or au cypress --run, alteratively I could do au cypress --start if I want to start the project before I ran the tests, or au cypress --run --start if I want to run cypress in non-interactive mode(headless I guess) and start the project before that.

2 Likes
#14

@shahabganji

Great, But I have a problem! How to end the process on terminal?

1 Like
#15

Lol good question :smile:

2 Likes
#16

Id expect it to be Ctrl+C?

2 Likes
#17

:joy::joy::joy: Manually yes. What about automatically?!

1 Like
#18

Lol sry missed the context

1 Like
#19

I’d imagine that run.default() should return a process handle, which will then be used with cross-platform killtree inside cypress.run().then(…) before cb().

2 Likes
#20

I think @khuongduybui is right, however, I don’t know how to expose that process, since I just imported the run method used in au run command and that does not return any process handler since there is no need in that scenario, the web server should be running on till we say not so. That being said, I came up with a workaround, based on the port of the application( e.g. 8080 in this case ) I found the process(pid) and killed it :wink:

I used find-process npm package to find the process information of the application running on port 8080, and used ps-node npm package to kill it.

so the cypress.ts file would look like the following:

// @ts-ignore
import * as cypress from 'cypress';
import * as config from '../../cypress.config';
import { CLIOptions } from 'aurelia-cli';

var find = require('find-process');
var ps = require( 'ps-node' );

import * as run from './run';

export default (cb) => {

  let hasRunProject = process.argv.find(x => x === "--start") || false;
  if (hasRunProject) {
    run.default();
  }

  if (CLIOptions.hasFlag('run')) {
    cypress
      .run(config)
      .then(results => {
        (results.totalFailed === 0 ? cb() : cb('Run failed!'));

        find('port', 8080)
          .then(function (list) {
            if (!list.length) {
              console.log('port 8080 is free now');
            } else {
              console.log('%s is listening port 8080', JSON.stringify(list[0]));
              // kill the process
              ps.kill(list[0].pid , () => {});
            }
          })

      }
      )
      .catch(cb);
  } else {
    cypress.open(config);
  }
};

and you can jus run the following command: au cypress --run --start
the --start is sth I invented :smile: to run the real application under the test.
Hope this helps.

1 Like