Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node - Execute command asynchronously and read results on completion

I have a suite of tests written with Playwright. I am trying to execute these tests from a separate suite of tests. In this separate suite of tests, I need to examine the results of the original results. This leads me to the following directory structure:

/
  /checks
    checks1.spec.js
  /tests
    tests1.spec.js
    tests2.spec.js
  playwright.config.js

My files look like this:

playwright.config.js

// @ts-check
const { devices } = require('@playwright/test');
    
/**
 * @see https://playwright.dev/docs/test-configuration
 * @type {import('@playwright/test').PlaywrightTestConfig}
 */
const config = {
  testDir: '.',
  timeout: 30 * 1000,
  expect: {
    timeout: 5000
  },
  forbidOnly: !!process.env.CI,
  retries: process.env.CI ? 2 : 0,
  workers: process.env.CI ? 1 : undefined,
  reporter: [
    ['html', { outputFolder: 'reports' } ]
  ],
  use: {
    actionTimeout: 0,
    trace: 'on-first-retry',
  },

  /* Configure projects for major browsers */
  projects: [
    {
      name: 'chromium',
      use: {
        ...devices['Desktop Chrome'],
      },
    }
  ]
};

module.exports = config;

tests1.spec.js

const { test, expect } = require('@playwright/test');

test.describe('Field Tests', () => {
  test('Should be required', async({ page }) => {
    await page.goto('http://localhost:8080');
    await expect(true).toBe(true);
  });
});

checks1.spec.js

const { exec } = require('child_process');
const { test, expect } = require('@playwright/test');

const command = 'npx playwright test --reporter=json ./tests/tests1.spec.js';

test.describe('Field', () => {
    test(`Require state`, async () => {
      const { stdout, stderr } = await exec(command);
            
      // Execute the test and get the results
      const buffer = child_process.execSync(command);
      const json = JSON.parse(buffer.toString()); 
      const results = json.suites[0].suites[0].specs;
        
      const status = results[0].tests[0].results[0].status;
      expect(status).toBe('passed');
    });
});

When I run npx playwright test --reporter=json ./tests/test1.spec.js, I receive the JSON output as I would expect. However, when I run npx playwright test checks, I receive a Socket instead of the JSON. How do I run the command and wait for the JSON to be returned? Thank you.

like image 306
Dev Avatar asked Oct 16 '25 06:10

Dev


1 Answers

It is not clear why your are executing tour command twice (once with await keyword and once with execSync function). However it can be resolved using events:

test.describe('Field', () => {
    test(`Require state`, async () => {
      const process = await exec(command);
            
      process.stdout.on('data', data => {
        // do something with the data here
      })
        
      process.on('exit', () => {
        // final checks (e.g. - expect) go here
      })
     
    });
});

If you want you can build a helper that will return the execution result as promise, thus support the await + async keywords

async cmd(command) {
 return new Promise((resolve, reject) => {
      const process = await exec(command);
      let result = data
      process.stdout.on('data', data => {
        result = data // any other format manipulations should be added here
      })
      process.stderr.on('data', reject)
      process.on('exit', () => resolve(result))
      
 })
}

Then, somewhere in your code just use:

const result = await cmd('your command goes here')
like image 157
ymz Avatar answered Oct 17 '25 20:10

ymz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!