enum Platform {
react = 'react',
vue = 'vue',
other = 'other',
}
type inputElement = HTMLTextAreaElement | HTMLInputElement
class ImitateUser {
private platfrom: Platform;
private inputElement: inputElement | null = null;
private text: string = '';
constructor(platfrom: Platform) {
this.platfrom = platfrom;
}
async inputValue(text: string, selector: string) {
try {
await this.when(() => !!document.querySelector(selector));
const element = document.querySelector(selector) as inputElement;
if (!['INPUT', 'TEXTAREA'].includes(element.tagName)) {
throw new Error('');
}
this.inputElement = element;
this.text = text;
switch (this.platfrom) {
case Platform.react:
this.reactInputValue();
break;
case Platform.vue:
this.vueInputValue();
break;
default:
this.otherInputValue();
}
} catch {
throw new Error('');
}
}
sleep = (duration: number) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(true);
}, duration);
});
};
when = (cb: () => boolean, cycle = 100, outtime = 3000) => {
const endNow = Date.now() + outtime;
return new Promise(async (resolve, reject) => {
while (true) {
if (cb()) {
break;
}
await this.sleep(cycle);
if (endNow < Date.now()) {
reject();
break;
}
}
resolve(true);
});
};
private reactInputValue = () => {
const element:any = this.inputElement;
let lastValue = element.value;
element.value = this.text;
let event = new Event('input', { bubbles: true });
let tracker = element._valueTracker;
if (tracker) {
tracker.setValue(lastValue);
}
element.dispatchEvent(event);
};
private vueInputValue = () => {
const element: any = this.inputElement;
element.value = this.text;
var event = document.createEvent('HTMLEvents');
event.initEvent('input', true, true);
event.eventType = 'message';
element.dispatchEvent(event);
};
private otherInputValue = ()=>{
this.inputElement.value = this.text;
let event = new Event('input', { bubbles: true });
element.dispatchEvent(event);
}
}
// React 模拟用户输入
new ImitateUser(Platform.react).inputValue('mondanzuo','.test')