Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

2.3K
Visualizações
Cómo probar material ui autocompletar con la biblioteca de pruebas de reacción

Estoy usando el componente de autocompletar material-ui y estoy tratando de probarlo usando react-testing-library

Componente :

 /* eslint-disable no-use-before-define */ import TextField from '@material-ui/core/TextField'; import Autocomplete from '@material-ui/lab/Autocomplete'; import React from 'react'; export default function ComboBox() { const [autocompleteInputValue, setAutocompleteInputValue] = React.useState(''); const [isAutocompleteOpen, setIsAutocompleteOpen] = React.useState(false); const renderInput = (params: any) => <TextField {...params} label='openOnFocus: false' variant='outlined' />; const getTitle = (option: any) => option.title; const handleAutocompleteInputChange = (event: any, value: string) => { setAutocompleteInputValue(value); }; const updateAutocompletePopper = () => { setIsAutocompleteOpen(!isAutocompleteOpen); }; return ( <Autocomplete id='autocompleteSearch' data-testid='autocomplete-search' disableClearable={true} renderOption={getTitle} getOptionLabel={getTitle} renderInput={renderInput} options={top100Films} clearOnEscape={true} onInputChange={handleAutocompleteInputChange} inputValue={autocompleteInputValue} open={isAutocompleteOpen} onOpen={updateAutocompletePopper} onClose={updateAutocompletePopper} style={{ width: 300 }} ListboxProps={{ 'data-testid': 'list-box' }} /> ); } // Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top export const top100Films = [ { title: 'The Shawshank Redemption', year: 1994 }, { title: 'The Godfather', year: 1972 }, { title: 'The Godfather: Part II', year: 1974 }, { title: 'The Dark Knight', year: 2008 }, { title: '12 Angry Men', year: 1957 }, { title: 'Schindlers List', year: 1993 }, { title: 'Pulp Fiction', year: 1994 }, { title: 'The Lord of the Rings: The Return of the King', year: 2003 }, { title: 'The Good, the Bad and the Ugly', year: 1966 }, { title: 'Fight Club', year: 1999 }, { title: 'The Lord of the Rings: The Fellowship of the Ring', year: 2001 }, { title: 'Star Wars: Episode V - The Empire Strikes Back', year: 1980 }, { title: 'Forrest Gump', year: 1994 }, { title: 'Inception', year: 2010 }, { title: 'The Lord of the Rings: The Two Towers', year: 2002 }, { title: 'One Flew Over the Cuckoos Nest', year: 1975 }, { title: 'Goodfellas', year: 1990 }, { title: 'The Matrix', year: 1999 }, { title: 'Seven Samurai', year: 1954 }, { title: 'Star Wars: Episode IV - A New Hope', year: 1977 }, { title: 'City of God', year: 2002 }, { title: 'Se7en', year: 1995 }, { title: 'The Silence of the Lambs', year: 1991 }, { title: 'Its a Wonderful Life', year: 1946 }, { title: 'Life Is Beautiful', year: 1997 }, { title: 'The Usual Suspects', year: 1995 }, { title: 'Léon: The Professional', year: 1994 }, { title: 'Spirited Away', year: 2001 }, { title: 'Saving Private Ryan', year: 1998 }, { title: 'Once Upon a Time in the West', year: 1968 }, { title: 'American History X', year: 1998 }, { title: 'Interstellar', year: 2014 }, { title: 'Casablanca', year: 1942 }, { title: 'City Lights', year: 1931 }, { title: 'Psycho', year: 1960 }, { title: 'The Green Mile', year: 1999 }, { title: 'The Intouchables', year: 2011 }, { title: 'Modern Times', year: 1936 }, { title: 'Raiders of the Lost Ark', year: 1981 }, { title: 'Rear Window', year: 1954 }, { title: 'The Pianist', year: 2002 }, { title: 'The Departed', year: 2006 }, { title: 'Terminator 2: Judgment Day', year: 1991 }, { title: 'Back to the Future', year: 1985 }, { title: 'Whiplash', year: 2014 }, { title: 'Gladiator', year: 2000 }, { title: 'Memento', year: 2000 }, { title: 'The Prestige', year: 2006 }, { title: 'The Lion King', year: 1994 }, { title: 'Apocalypse Now', year: 1979 }, { title: 'Alien', year: 1979 }, { title: 'Sunset Boulevard', year: 1950 }, { title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb', year: 1964, }, { title: 'The Great Dictator', year: 1940 }, { title: 'Cinema Paradiso', year: 1988 }, { title: 'The Lives of Others', year: 2006 }, { title: 'Grave of the Fireflies', year: 1988 }, { title: 'Paths of Glory', year: 1957 }, { title: 'Django Unchained', year: 2012 }, { title: 'The Shining', year: 1980 }, { title: 'WALL·E', year: 2008 }, { title: 'American Beauty', year: 1999 }, { title: 'The Dark Knight Rises', year: 2012 }, { title: 'Princess Mononoke', year: 1997 }, { title: 'Aliens', year: 1986 }, { title: 'Oldboy', year: 2003 }, { title: 'Once Upon a Time in America', year: 1984 }, { title: 'Witness for the Prosecution', year: 1957 }, { title: 'Das Boot', year: 1981 }, { title: 'Citizen Kane', year: 1941 }, { title: 'North by Northwest', year: 1959 }, { title: 'Vertigo', year: 1958 }, { title: 'Star Wars: Episode VI - Return of the Jedi', year: 1983 }, { title: 'Reservoir Dogs', year: 1992 }, { title: 'Braveheart', year: 1995 }, { title: 'M', year: 1931 }, { title: 'Requiem for a Dream', year: 2000 }, { title: 'Amélie', year: 2001 }, { title: 'A Clockwork Orange', year: 1971 }, { title: 'Like Stars on Earth', year: 2007 }, { title: 'Taxi Driver', year: 1976 }, { title: 'Lawrence of Arabia', year: 1962 }, { title: 'Double Indemnity', year: 1944 }, { title: 'Eternal Sunshine of the Spotless Mind', year: 2004 }, { title: 'Amadeus', year: 1984 }, { title: 'To Kill a Mockingbird', year: 1962 }, { title: 'Toy Story 3', year: 2010 }, { title: 'Logan', year: 2017 }, { title: 'Full Metal Jacket', year: 1987 }, { title: 'Dangal', year: 2016 }, { title: 'The Sting', year: 1973 }, { title: '2001: A Space Odyssey', year: 1968 }, { title: 'Singin in the Rain', year: 1952 }, { title: 'Toy Story', year: 1995 }, { title: 'Bicycle Thieves', year: 1948 }, { title: 'The Kid', year: 1921 }, { title: 'Inglourious Basterds', year: 2009 }, { title: 'Snatch', year: 2000 }, { title: '3 Idiots', year: 2009 }, { title: 'Monty Python and the Holy Grail', year: 1975 }, ];

Dependiendo de la opción elegida de autocompletar, estoy haciendo otras cosas, como renderizar un chip, otro componente, etc. Pero para simplificar, inicialmente solo estoy probando que, cuando el usuario se enfoca en el campo de entrada, la ventana emergente es que se muestra para que luego pueda hacer clic en una opción en esta ventana emergente y probar que todo lo demás funciona como se esperaba. Estoy verificando la ventana emergente usando data-testid que asigné al cuadro de lista a través de ListboxProps prop de autocompletar:

Prueba :

 import { fireEvent, getByRole as globalGetByRole, getByText as globalGetByText, render, } from '@testing-library/react'; import React from 'react'; import ComboBox, { top100Films } from './AutoComplete'; test('that autocomplete works', async () => { const { getByTestId, getByRole, queryByRole } = render(<ComboBox />, {}); const AutoCompleteSearch = getByTestId('autocomplete-search'); const Input = globalGetByRole(AutoCompleteSearch, 'textbox'); expect(queryByRole('listbox')).toBeNull(); fireEvent.mouseDown(Input); const ListBox = getByRole('listbox'); expect(ListBox).toBeDefined(); const menuItem1 = globalGetByText(ListBox, top100Films[0].title); fireEvent.click(menuItem1); expect(queryByRole('listbox')).toBeNull(); fireEvent.mouseDown(Input); const ListBoxAfter = getByRole('listbox'); expect(ListBoxAfter).toBeDefined(); const menuItem2 = globalGetByText(ListBoxAfter, top100Films[1].title); fireEvent.click(menuItem2); expect(queryByRole('listbox')).toBeNull(); });

Pero esto está fallando con: Unable to find an element by: [data-testid="list-box"] . ¿Qué estoy haciendo mal?

EDITAR : disparé mouseDown en Input y pude probar con éxito que la ventana emergente está abierta. Usé el rol de listbox de lista en lugar de un data-testid para verificar que la ventana emergente se haya abierto. Lo mismo se puede hacer con data-testid también. Luego, elegí un elemento de las opciones de autocompletar y la ventana emergente se cerró. Ahora, traté de abrir la ventana emergente nuevamente por segunda vez y aquí, falla nuevamente. No se puede abrir por segunda vez usando el evento mouseDown .

over 4 years ago · Santiago Trujillo
11 Respostas
Responde à pergunta

0

el problema aquí es que la función de autocompletar usa portales de forma predeterminada y muestra las opciones en el cuerpo... que no está presente en el contenedor renderizado, debe mostrar la función de autocompletar en el cuerpo del documento

over 4 years ago · Santiago Trujillo Relatório

0

Dado que los elementos de la lista no son "visibles" en el propio DOM, debe utilizar un enfoque diferente.

Debe ubicar los elementos DOM de autocompletar e ingresar en los que desencadenará eventos.

El autocompletado generalmente se encuentra en el DOM por el atributo de rol, por ejemplo, role="combobox" , pero es mejor darle un identificador único como data-testid="autocomplete"

El siguiente código muestra cómo probar la selección de elementos en autocompletar:

 const autocomplete = getByTestId('autocomplete'); const input = within(autocomplete).querySelector('input') autocomplete.focus() // assign value to input field fireEvent.change(input, { target: { value: value } }) await wait() // navigate to the first item in the autocomplete box fireEvent.keyDown(autocomplete, { key: 'ArrowDown' }) await wait() // select the first item fireEvent.keyDown(autocomplete, { key: 'Enter' }) await wait() // check the new value of the input field expect(input.value).toEqual('some_value')

Debe insertar un valor en el elemento de entrada y luego activar el cambio. Después de eso, se abre el cuadro de lista que permite seleccionar el primer valor presionando la tecla Intro. El valor seleccionado reemplazará el valor inicial ingresado utilizado para buscar/abrir el autocompletado.

over 4 years ago · Santiago Trujillo Relatório

0

// make sure autocomplete reactions/results do not already exist expect(screen.queryByText(/Loading/)).not.toBeInTheDocument() expect(screen.queryByText(/Van Halen/)).not.toBeInTheDocument() // fill out autocomplete const faveBand = screen.getByLabelText(/Favorite Band/) userEvent.type(faveBand, 'Van H') expect(faveBand).toHaveValue('Van H') // witness autocomplete working expect(screen.getByText(/Loading/)).toBeInTheDocument() // wait for response (i used an async Material-UI autocomplete) // favebands is a data-testid attribute value in my autocomplete // component, eg ListboxProps={{ 'data-testid': 'favebands' }} await waitFor(() => getByTestId('favebands')) // verify autocomplete items are visible expect(screen.getByText(/Van Halen/)).toBeInTheDocument() // click on autocomplete item const faveBandItem = screen.getByText('Van Halen') userEvent.click(faveBandItem) // verify autocomplete has new value expect(faveBand).toHaveValue('Van Halen')

Importo userEvent, waitFor y screen así...

 import { screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event'
over 4 years ago · Santiago Trujillo Relatório

0

En primer lugar, debe asegurarse de que las opciones no sean una matriz vacía, luego haga lo siguiente:

 const autocomplete = getByTestId('autocomplete'); const input = within(autocomplete).getByRole('textbox') autocomplete.focus() // the value here can be any string you want, so you may also consider to // wrapper it as a function and pass in inputValue as parameter fireEvent.change(input, { target: { value: 'a' } }) fireEvent.keyDown(autocomplete, { key: 'ArrowDown' }) fireEvent.keyDown(autocomplete, { key: 'Enter' })
over 4 years ago · Santiago Trujillo Relatório

0

Puede usar la función onInputChange para averiguar si se ha cambiado la entrada.

 test('my test', () => { const { container } = render( <Autocomplete noOptionsText="no Option" getOptionLabel={(option) => option.name} onInputChange={(__, value) => { //implements logic when value is selected }} multiple id="my-id" options={[{ name: 'My name 1' }]} renderInput={(params) => <TextField {...params} label="My Label" />} /> ) const input = container.querySelector('#my-id') fireEvent.change(input, { target: { value: { name: 'My name 1' } } }) })

over 4 years ago · Santiago Trujillo Relatório

0

necesitas ir siguiendo:

  1. haga clic en autocompletar
  2. opción de búsqueda
  3. Seleccionar opción
 const label = 'label of your autocomplete' const textBox = screen.getByRole('textbox', { name: label, }); userEvent.click(textBox); // wait for option to appear await waitFor(() => { screen.getByRole('listbox'); }); // grab option const opt = screen.getByRole('option', { name: /The Great Dictator/i, }); // select it userEvent.click(opt);
over 4 years ago · Santiago Trujillo Relatório

0

Aquí está mi opinión usando react-testing-library -> user-event. Para que funcione, tuve que asignar data-testid a las opciones de menú que se muestran en la función de autocompletar.

 const autoComplete = screen.getByRole("combobox"); expect(autoComplete).toBeVisible(); const autoCompleteDropdown = screen.getByRole("button", { name: "Open" }); // Autocomplete dropdown button. expect(autoCompleteDropdown).toBeVisible(); userEvent.click(autoCompleteDropdown); // Autocomplete dropdown view. expect(screen.getByRole("presentation")).toBeVisible(); // click on administrator menu option in autocomplete. userEvent.click(screen.getByTestId("option1")); // imitate click away(this is only required if you have disableCloseOnSelect is enabled. userEvent.click(document.body); expect(screen.queryByRole("presentation")).not.toBeInTheDocument(); //Verify autocomplete shows the correct value. expect(screen.getByText("option1")).toBeVisible();
over 4 years ago · Santiago Trujillo Relatório

0

encontré este como mi solución

 const autoComplete = getByLabelText('component-autoComplete'); const input = within(autoComplete).getByRole('textbox'); autoComplete.focus(); fireEvent.change(input, { target: { value: 'mockValue' } }); fireEvent.keyDown(autoComplete, { key: 'ArrowDown' }); fireEvent.keyDown(autoComplete, { key: 'Enter' }); expect(input).toHaveValue('mockValue');
over 4 years ago · Santiago Trujillo Relatório

0

Todavía no lo he probado en el ejemplo de mui, pero lo hice en mi aplicación y funciona de la siguiente manera:

 userEvent.type(screen.getByRole("textbox", {name: /attendees/i}), "Bertrand") userEvent.click(screen.getByText(/bertrand/i))

simule un tipo de evento de usuario (aquí, Bertrand , en su ejemplo: Schindlers ), donde el nombre dado a screen.getByRole es el valor de la etiqueta de su autocompletar (en su ejemplo: openOnFocus: false . luego simule un clic en el esperado texto (es decir: un texto que está presente en sus opciones, por ejemplo Schindlers ).

NB: lo he probado en @mui/material AutoComplete no del laboratorio

over 4 years ago · Santiago Trujillo Relatório

0

En mi caso, necesitaba ingresar valores en dos campos de autocompletar para habilitar el botón de página siguiente. Modifiqué las respuestas principales porque no funcionaba para mí.

 const autocompleteClient = renderResult.getByTestId('client'); const inputClient = autocompleteClient.querySelector('input'); autocompleteClient.focus(); // assign value to input field of client fireEvent.change(inputClient!!, { target: { value: 'Client 1' } }) // presentation role is for the options of the autocomplete await renderResult.findAllByRole('presentation'); fireEvent.keyDown(autocompleteClient, { key: 'ArrowDown' }) fireEvent.keyDown(autocompleteClient, { key: 'Enter' }) const autocompleteProposal = renderResult.getByTestId('proposal-no'); const inputProposal = autocompleteProposal.querySelector('input'); autocompleteProposal.focus(); fireEvent.change(inputProposal!!, { target: { value: 'proposal 1' } }) await renderResult.findAllByRole('presentation'); fireEvent.keyDown(autocompleteProposal, { key: 'ArrowDown' }) fireEvent.keyDown(autocompleteProposal, { key: 'Enter' }) expect(screen.getByText('Next')).toBeEnabled(); fireEvent.click(screen.getByText('Next')); expect(screen.getByText('Generate')).toBeDisabled();

Donde renderResult = render(<YourComponent/>);

over 4 years ago · Santiago Trujillo Relatório

0

Pude encontrar una solución que permite esperar a que aparezca el menú de opciones y validar esas opciones.

Los pasos clave para poder utilizar las opciones devueltas por la API simulada fueron:

  1. Haga clic en el botón "Abrir" que forma parte del componente Autocompletar
  2. Elementos waitFor() con role="option" para que aparezcan en el DOM

También envío la entrada a HTMLInputElement ya que mis pruebas están escritas en TypeScript.

 test("sends API request on search", async () => { // arrange render(<Dropdown />); // act const autocomplete = screen.getByRole("combobox"); const input: HTMLInputElement = within(autocomplete).getByLabelText( "Select a template" ) as HTMLInputElement; const searchValue = "react-boiler"; const templateValue = "react-boilerplate"; autocomplete.focus(); // open autocomplete dropdown menu within(autocomplete).getByLabelText("Open").click(); const options = await screen.findAllByRole("option"); // Perform some tests specific to the options provided to the dropdown // expect(options).toHaveLength(7); // assign value to input field fireEvent.change(input, { target: { value: searchValue } }); // navigate to the first item in the autocomplete box fireEvent.keyDown(autocomplete, { key: "ArrowDown" }); // select the first item fireEvent.keyDown(autocomplete, { key: "Enter" }); // check the new value of the input field expect(input.value).toEqual(templateValue); });
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda