Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

block when simulate user input #870

Open
supperchong opened this issue Dec 2, 2019 · 0 comments
Open

block when simulate user input #870

supperchong opened this issue Dec 2, 2019 · 0 comments

Comments

@supperchong
Copy link

supperchong commented Dec 2, 2019

  • Version: node v12.13.0
  • Platform: 64-bit (Windows)
  • Subsystem: cmd/PowerShell

Sometimes, we want to simulate user input , for example we need test when we write a npm module.
like following code ,it will block at the second prompt , can't see the second question.

const inquirer = require('inquirer');
const choices = [
    {
        name: "test1",
        value: "test1"
    },
    {
        name: "test2",
        value: "test2"
    }
];
const choices2 = [
    {
        name: "test1",
        value: "test1"
    },
    {
        name: "test2",
        value: "test2"
    }
];
(async ()=>{
  let p1= inquirer.prompt({
    name: 'boilerplateInfo',
    type: 'list',
    message: 'Please select a boilerplate type',
    choices: choices2,
    pageSize: choices2.length,
  });

  //it will block
  setTimeout(()=>{
    process.stdin.emit('keypress','\r') 
  },100)
  
  await p1

  await inquirer.prompt({
    name: 'boilerplateInfo',
    type: 'list',
    message: 'Please select a boilerplate type',
    choices: choices2,
    pageSize: choices2.length,
  });
})()

look at source code, when one prompt over, the readline instance will pause process.stdin before close , It works good when it's interacting with the reality user. Moreover pause process.stdin is to fix the similar bug , issues: Make inquirer.prompt() blocking, Fix bug to properly close readline, readline: pause stdin before turning off terminal raw mode

But when we want to simulate user input, it block. I find some solution, but i don't know the reason.
My problem is what's the right way to simulate user input ?

And I find some strange problems with readline.close .Maybe these are node bugs. Inquirer prompt use different readline instance to hanlde questions. I know you intend refactor inquirer . Consider if use one readline instance ? @SBoudrias

  1. solution one:resume process.stdin after close and wait a little time
const inquirer = require('inquirer');
const inquirer = require('inquirer');
const choices = [
    {
        name: "test1",
        value: "test1"
    },
    {
        name: "test2",
        value: "test2"
    }
];
const choices2 = [
    {
        name: "test1",
        value: "test1"
    },
    {
        name: "test2",
        value: "test2"
    }
];
function sleep(time) {
    return new Promise(resolve => {
        setTimeout(resolve, time);
    });
}
(async () => {
    let p1 = inquirer.prompt({
        name: 'boilerplateInfo',
        type: 'list',
        message: 'Please select a boilerplate type',
        choices: choices2,
        pageSize: choices2.length,
    });
    setTimeout(() => {
        p1.ui.rl.input.emit('keypress', '\r')
    }, 100)
    await p1.then(() => p1.ui.rl.input.resume())
    await sleep(10) //this is neccessary
    let p2 = inquirer.prompt({
        name: 'boilerplateInfo',
        type: 'list',
        message: 'Please select a boilerplate type',
        choices: choices2,
        pageSize: choices2.length,
    });
    process.stdin.emit('keypress', '\r')
})()
  1. solution two: emit keypress immediately
const choices = [
    {
        name: "test1",
        value: "test1"
    },
    {
        name: "test2",
        value: "test2"
    }
];
const choices2 = [
    {
        name: "test1",
        value: "test1"
    },
    {
        name: "test2",
        value: "test2"
    }
];
const inquirer = require('inquirer');
(async () => {
    let p1 = inquirer.prompt({
        name: 'boilerplateInfo',
        type: 'list',
        message: 'Please select a boilerplate type',
        choices: choices2,
        pageSize: choices2.length,
    });
    // setTimeout(() => {
    process.stdin.emit('keypress', '\r')
    // }, 100)
    await p1
    let p2 = inquirer.prompt({
        name: 'boilerplateInfo',
        type: 'list',
        message: 'Please select a boilerplate type',
        choices: choices2,
        pageSize: choices2.length,
    });
    process.stdin.emit('keypress', '\r')
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant