Je suis chargé de l'exploration du site Web construit avec React. J'essaie de remplir les champs de saisie et de soumettre le formulaire en utilisant des injections javascript à la page (soit Selenium ou Webview dans un mobile). Cela fonctionne comme un charme sur tous les autres sites + technologies mais React semble être une vraie douleur.
voici donc un exemple de code
var email = document.getElementById( 'email' );
email.value = '[email protected]';
I la valeur change sur l'élément d'entrée DOM, mais le React ne déclenche pas l'événement change.
J'ai essayé une multitude de façons différentes d'obtenir le React pour mettre à jour l'état.
var event = new Event('change', { bubbles: true });
email.dispatchEvent( event );
en vain
var event = new Event('input', { bubbles: true });
email.dispatchEvent( event );
ca ne fonctionne pas
email.onChange( event );
ca ne fonctionne pas
Je ne peux pas croire que l'interaction avec React a été rendue si difficile. J'apprécierais grandement toute aide.
Je vous remercie
React écoute l'événement input
des champs de texte.
Vous pouvez modifier la valeur et déclencher manuellement un événement d'entrée, et le gestionnaire onChange
de react déclenchera:
class Form extends React.Component {
constructor(props) {
super(props)
this.state = {value: ''}
}
handleChange(e) {
this.setState({value: e.target.value})
console.log('State updated to ', e.target.value);
}
render() {
return (
<div>
<input
id='textfield'
value={this.state.value}
onChange={this.handleChange.bind(this)}
/>
<p>{this.state.value}</p>
</div>
)
}
}
ReactDOM.render(
<Form />,
document.getElementById('app')
)
document.getElementById('textfield').value = 'foo'
const event = new Event('input', { bubbles: true })
document.getElementById('textfield').dispatchEvent(event)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app'></div>
Cette solution acceptée semble ne pas fonctionner dans React> 15.6 (y compris React 16) à la suite de modifications apportées à la déduplication des entrées et aux événements de modification).
Vous pouvez voir la discussion React ici: https://github.com/facebook/react/issues/10135
Et la solution de contournement suggérée ici: https://github.com/facebook/react/issues/10135#issuecomment-314441175
Reproduit ici pour plus de commodité:
Au lieu de
input.value = 'foo';
input.dispatchEvent(new Event('input', {bubbles: true}));
Vous utiliseriez
function setNativeValue(element, value) {
const valueSetter = Object.getOwnPropertyDescriptor(element, 'value').set;
const prototype = Object.getPrototypeOf(element);
const prototypeValueSetter = Object.getOwnPropertyDescriptor(prototype, 'value').set;
if (valueSetter && valueSetter !== prototypeValueSetter) {
prototypeValueSetter.call(element, value);
} else {
valueSetter.call(element, value);
}
}
puis
setNativeValue(input, 'foo');
input.dispatchEvent(new Event('input', { bubbles: true }));