question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

trigger "search" event is during type with {enter}

See original GitHub issue

Current behavior:

The {enter} key functionality is not triggered.

Desired behavior:

After enter key simulated is pressed, it should display info in the page

Test code to reproduce

This is the code I have for testing:

it('should render 20 articles if I write `México` in the search field', () => {
  const resultText = `Se encontraron 20 resultados de "México". `;
        
  cy.get('#search').should('exist');
  cy.get('#search').clear().type('RandomText{enter}');
});

app.js:

export const apiKey = "";
const defaultSource = 'buzzfeed';
const sourceSelector = document.querySelector('#sourceSelector');
const inputSearch = document.querySelector('input[type="search"]');
const newsArticles = document.querySelector('main');
const statusBar = document.querySelector('.status');
const imgNotFound = "https://stockpictures.io/wp-content/uploads/2020/01/image-not-found-big.png";

window.addEventListener('load', e => {

  sourceSelector.addEventListener('change', evt => updateNews(evt.target.value));
  updateNewsSources().then(() => {
    sourceSelector.value = defaultSource;
    updateNews();
  });

  inputSearch.addEventListener('search', e => {
    queryNews(e.target.value)
  })

  networkStatus()

  window.addEventListener('online', networkStatus);
  window.addEventListener('offline', networkStatus);
});

export async function getJSON(url) {
  const response = await fetch(url);
  const json = await response.json();
  
  return json;
}

export async function updateNewsSources() {
  const json = await getJSON(`https://newsapi.org/v2/sources?apiKey=${apiKey}`);

  sourceSelector.innerHTML =
    json.sources
      .map(source => `<option value="${source.id}">${source.name}</option>`)
      .join('\n');
}

export async function updateNews(source = defaultSource) {
  newsArticles.innerHTML = '';
  const json = await getJSON(`https://newsapi.org/v2/top-headlines?sources=${source}&sortBy=top&apiKey=${apiKey}`);
  
  newsArticles.innerHTML = json.articles.map(createArticle).join('\n');
}

export async function queryNews(query) {
  newsArticles.innerHTML = '';
  const json = await getJSON(`https://newsapi.org/v2/everything?q=${query}&apiKey=${apiKey}`);
  
  newsArticles.innerHTML = json.articles.map(createArticle).join('\n');
  document.getElementById('results').innerHTML = `Se encontraron <strong>${Object.keys(json.articles).length}</strong> resultados de <strong>"${query}"</strong>. `;
  inputSearch.value = ""
}

export function createArticle(article) {
  return `
      <div class="article" title="${article.title}">
        <a href="${article.url}">
          <div class="article-img">
            <img src="${article.urlToImage ? article.urlToImage : imgNotFound}" />
          </div>
          <div class="article-body">
            <h2 class="article-title">${article.title}</h2>
            <p>${article.description ? article.description : "Lorem Ipsum"}</p>
          </div>
        </a>
      </div>
      `;
}

export function networkStatus(sb) {
  sb = sb || statusBar;

  if (navigator.onLine) {
    sb.innerHTML = ""
    sb.style.display = "none"
    
    console.log('online');
  } else {
    sb.style.display = "block"
    sb.innerHTML = "Estas Offline"
    
    console.log('offline')
  }
}

index.html:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>News</title>
  <link rel="stylesheet" href="style.css" />
  <link rel="manifest" href="manifest.json" />

  <!-- The core Firebase JS SDK is always required and must be listed first -->
  <script src="https://www.gstatic.com/firebasejs/7.13.2/firebase-app.js"></script>
  <script src="https://www.gstatic.com/firebasejs/7.12.0/firebase-messaging.js"></script>

</head>

<body>
  <div id="statusBar" class="status"></div>
  <header>  
    <h1>News</h1>
    <div class="search-bar">
      <input type="search" placeholder="Buscar..." name="Buscar" id="search">
    </div>
    <div class="select">
      <select id="sourceSelector"></select>
    </div>    
  </header>
  <p id="results"></p>
  <main></main>
  <script src="app.js" type="module"></script>
</body>

</html>

style.css:

@import url('https://fonts.googleapis.com/css?family=Roboto+Mono&display=swap');
body {
  font-family: 'Roboto Mono', monospace;
  font-weight: 300;
  padding: 1em 3em;
}

h1 {
  text-transform: uppercase;
  font-weight: 300;
}

.status {
  background: #ef4e4e;
  color: white;
  font-weight: bolder;
  padding: 7px;
}

header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  font-size: 1em;
  position: relative;
}

#results {
  margin-top: 0;
}

main {
  display: grid;
  grid-gap: 30px;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  grid-auto-rows: max-content;
  grid-auto-flow: row dense;
}

.select {
  position: relative;
  display: flex;
  align-items: center;
}

select {
  font-family: 'Roboto Mono', monospace;
  border: .2em solid black;
  border-radius: 0;
  -webkit-appearance: none;
  -moz-appearance: none;
  -ms-appearance: none;
  padding: 1em;
}

.select:after {
  content: "\25BC";
  display: block;
  position: absolute;
  right: 20px;
  cursor: pointer;
  pointer-events: none;
}

.search-bar {
  flex-grow: .9;
}

.search-bar input {
  width: 100%;
  font-family: 'Roboto Mono', monospace;
  border: .2em solid black;
  font-size: 15px;
  padding: 8px;
}

.search-bar input:focus {
  outline-color: transparent;
  outline-style: none;
}

/* select::after {
  content: "\25BC";
  display: block;
  position: absolute;
  top: 0;
  right: 0;
  padding: 0 1em;
  background: #34495e;
  cursor: pointer;
  pointer-events: none;
  -webkit-transition: .25s all ease;
  -o-transition: .25s all ease;
  transition: .25s all ease;
  height: 40px;
  width: 40px;
} */

.article {
  word-wrap: break-word;
  background-color: #fff;
  background-clip: border-box;
  border: 1px solid rgba(0, 0, 0, .125);
  border-radius: .25rem;
  box-shadow: 4px 6px 7px 1px rgba(0, 0, 0, 0.75);
}

.article-body {
  padding: 1.25rem;
}

.article-title {
  margin-bottom: .75rem;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.article a, .article a:visited {
  text-decoration: none;
  color: inherit;
}

.article img {
  width: 100%;
  height: 13em;
}

I left here a video evidence to see the error: https://www.loom.com/share/dbccb6394a934222a3854b5973c1609c

Versions

Cypress: 4.5.0 Browser: Google Chrome, Version 81.0.4044.138 (Official Build) (64-bit) OS: Windows 10 Enterprise, 64 bits

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
jennifer-shehanecommented, May 19, 2020

Ok, I’ve simplified the example. This is not working because you are listening to the “search” event to be fired in order to display the search results. Cypress does not trigger the “search” event. It seems the “search” event is also non-standard, so I’m not sure we would build in specific support for this at this time. The search event isn’t even support in Firefox.

This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future. https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/search_event

Workaround

Manually trigger the search event from Cypress after typing using .trigger().

it('should render results', () => {
  cy.visit('index.html')
  cy.get('#search').should('exist');
  cy.get('#search').clear().type('random{enter}')
    .trigger('search')
  cy.contains('Searched for: "random"') 
})
Screen Shot 2020-05-19 at 4 59 28 PM

Failing example

index.html

<html lang="en">
<body>
  <input type="search" id="search">
  <p id="results"></p>
  <script>
    const search = document.getElementById('search')
    const results = document.getElementById('results')

    search.addEventListener('search', (e) => {
      results.innerHTML = `Searched for: "${e.target.value}"`
    })
  </script>
</body>
</html>

spec.js

it('should render results', () => {
  cy.visit('index.html')
  cy.get('#search').should('exist');
  cy.get('#search').clear().type('random{enter}');
  // fails because the search event wasn't triggered from type
  cy.contains('Searched for: "random"') 
})
Screen Shot 2020-05-19 at 4 58 21 PM
1reaction
jennifer-shehanecommented, May 14, 2020

Can you provide a failing test case showing the issue? I’m not sure what’s supposed to happen when you click enter. Clicking enter outside of Cypress with the example provided does nothing.

Screen Shot 2020-05-14 at 1 46 23 PM
Read more comments on GitHub >

github_iconTop Results From Across the Web

How to trigger search input event using a button click
Note that keydown , keypress and keyup events carry with them information about the modifier keys Ctrl , Shift and Alt in the...
Read more >
How To Trigger Button Click on Enter - W3Schools
Trigger a button click on keyboard "enter" with JavaScript. Trigger a Button Click on Enter. Press the "Enter" key inside the input field...
Read more >
.keypress() | jQuery API Documentation
To trigger the event manually, apply .keypress() without an argument: ... Show the event object when a key is pressed in the input....
Read more >
JavaScript | Trigger a button on ENTER key - GeeksforGeeks
keyup(): This event occurs when a keyboard key is released. The method either triggers the keyup event, or to run a function when...
Read more >
HTMLInputElement: search event - Web APIs - MDN Web Docs
The search event is fired when a search is initiated using an <input> element of type="search" . There are several ways a search...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found