Javier Arias
Javier Arias

Reputation: 2488

How to delete existing text from input using Puppeteer?

I'm trying to test amending text in an editable input which contains the title of the current record - and I want to able to test editing such text, replacing it with something else.

I know I can use await page.type('#inputID', 'blah'); to insert "blah" into the textbox (which in my case, having existing text, only appends "blah"), however, I cannot find any page methods1 that allow deleting or replacing existing text.

Upvotes: 68

Views: 82601

Answers (9)

Vaviloff
Vaviloff

Reputation: 16856

You can use page.evaluate to manipulate DOM as you see fit:

await page.evaluate( () => document.getElementById("inputID").value = "")

However sometimes just manipulating a given field might not be enough (a target page could be an SPA with event listeners), so emulating real keypresses is preferable. The examples below are from the informative issue in puppeteer's Github concerning this task.

Here we press Backspace as many times as there are characters in that field:

const inputValue = await page.$eval('#inputID', el => el.value);
// focus on the input field
await page.click('#inputID');
for (let i = 0; i < inputValue.length; i++) {
  await page.keyboard.press('Backspace');
}

Another interesting solution is to click the target field 3 times so that the browser would select all the text in it and then you could just type what you want:

const input = await page.$('#inputID');
await input.click({ clickCount: 3 })
await input.type("Blah");

Upvotes: 135

Felix K.
Felix K.

Reputation: 15683

If you are not interested in simulating any key events, you could also use puppeteer's page.$eval method as a concise means to remove the textarea's value...

await page.$eval('#inputID', el => el.value = '');
await page.type('#inputID', 'blah');

...or even completely replace the value in one step, without simulating the subsequent typing:

await page.$eval('#inputID', el => el.value = 'blah');

Upvotes: 15

Victor Cordeiro Costa
Victor Cordeiro Costa

Reputation: 2194

The most clean way for me is:

  • Setup
const clearInput = async (page, { selector }) => {
  const input = await page.$(selector)
  await input.click({ clickCount: 3 })
  await page.keyboard.press('Backspace')
}
  • Usage
const page = await context.newPage()

await clearInput(page, { selector: 'input[name="session[username_or_email]"]' })
await clearInput(page, { selector: 'input[name="session[password]"]' })

Upvotes: 1

Gleb Dolzikov
Gleb Dolzikov

Reputation: 834

This works perfect for "clear only" method:

const input = await page.$('#inputID');
await input.click({ clickCount: 3 })
await page.keyboard.press('Backspace')

Upvotes: 6

neonidian
neonidian

Reputation: 1263

Use the Keyboard API which simulates keystrokes:

await page.focus(css);            // CSS selector of the input element
await page.keyboard.down('Shift'); 
await page.keyboard.press('Home');
await page.keyboard.up('Shift');  // Release the pressed 'Shift' key
await page.keyboard.press('Backspace');

This keystroke is cross-platform as opposed to using ctrl + A(does not work in Mac to select all characters in a input field)

Upvotes: 3

Sawan Rawath
Sawan Rawath

Reputation: 1

someField.type("");

Pass the empty string before typing your content.

This worked for me.

Upvotes: -3

Grant Miller
Grant Miller

Reputation: 29057

You can use the page.keyboard methods to change input values, or you can use page.evaluate().

Replace All Text:

// Using page.keyboard:

await page.focus('#example');
await page.keyboard.down('Control');
await page.keyboard.press('A');
await page.keyboard.up('Control');
await page.keyboard.press('Backspace');
await page.keyboard.type('foo');

// Using page.evaluate:

await page.evaluate(() => {
  const example = document.getElementById('example');
  example.value = 'foo';
});

Append Text:

// Using page.keyboard:

await page.focus('#example');
await page.keyboard.press('End');
await page.keyboard.type(' bar qux');

// Using page.evaluate:

await page.evaluate(() => {
  const example = document.getElementById('example');
  example.value += ' bar qux';
});

Backspace Last Character:

// Using page.keyboard:

await page.focus('#example');
await page.keyboard.press('End');
await page.keyboard.press('Backspace');

// Using page.evaluate:

await page.evaluate(() => {
  const example = document.getElementById('example');
  example.value = example.value.slice(0, -1);
});

Delete First Character:

// Using page.keyboard:

await page.focus('#example');
await page.keyboard.press('Home');
await page.keyboard.press('Delete');

// Using page.evaluate:

await page.evaluate(() => {
  const example = document.getElementById('example');
  example.value = example.value.slice(1);
});

Upvotes: 35

Tzvika Merchav
Tzvika Merchav

Reputation: 44

above answers has an ESLint issues. the following solution passing ESLint varification:

await page.evaluate(
  (selector) => { (document.querySelector(selector).value = ''); },
  inputBoxSelector,
);

Upvotes: 1

levy9527
levy9527

Reputation: 49

Well, the reason you want to delete existing text generally may be want to replace it.

You can use page.evalute

let title = getTitle()
let selector = getSelector()

await page.evaluate(
  ({selector, title}) => {
    let el = document.querySelector(selector)
    if ('value' in el) el.value = title
    else el.innerText = title
  },
  {selector, title}
)

Upvotes: 0

Related Questions