Mailto HREF link

📺 Watch this recipe explained in the video Test Mailto HREF Anchor Linksopen in new window.

<a
  id="send"
  href="mailto:[email protected]?subject=The%20subject%20of%20the%20email&body=The%20body%20of%20the%20email"
  >Send an email</a
>

Let's use this utility function to parse mailto:... string

// string parameter s is like "mailto:...?param1=...&param2=..."
// where each parameter is URL-encoded
function parseMailto(s) {
  const [start, params] = s.split('?')
  const recipient = start.split(':')[1]
  const result = { recipient }
  params.split('&').forEach((param) => {
    const [key, encoded] = param.split('=')
    result[key] = decodeURIComponent(encoded)
  })
  return result
}

We cannot click on the link, since in most cases it will launch an external application registered with the operating system that handles sending an email (like Outlook).

// 🚨 DOES NOT WORK, THE TEST WILL HANG
cy.get('a#send')

Tip: You can the browser from opening the email client by registering from the test itself a "click" event handler.

// we can click, but it does nothing
cy.get('a#send')
  .invoke('on', 'click', (e) => {
    console.log('stop the default browser behavior')
    e.preventDefault()
  })
  .click()

Instead, trust the operating system and the email standards. If the mailto link is correct, the browser and your email program should work with it. The test can confirm the <A> HREF attribute is present, parse the attribute value, and confirm each parameter of the email to send has the expected value.

cy.get('a#send')
  .should('have.attr', 'href')
  // yields the value of the "href" attribute
  .should('match', /^mailto:/)
  // parse the URL into recipient, subject, body fields
  .then(parseMailto)
  .should('deep.equal', {
    recipient: '[email protected]',
    subject: 'The subject of the email',
    body: 'The body of the email',
  })