2015-01-02 19 views
8

Tôi cố gắng để tự động hóa các biểu mẫu đăng nhập của ứng dụng web Instagram:Mẫu tạo ra với Phản ứng không cập nhật các đối tượng nhà nước ủng hộ

https://instagram.com/accounts/login/

Với đoạn mã sau (bạn có thể chạy nó trên Chrome console) :

var frm = window.frames[1].document.forms[0]; 
frm.elements[0].value = 'qacitester'; 
frm.elements[1].value = 'qatester'; 
frm.elements[2].click(); 

Mặc dù các yếu tố đầu được dân cư, khi tôi theo dõi các yêu cầu XHR, tôi thấy điều này được đăng tải:

username = & password = & ý định =

hơn này:

username = qacitester & password = qatester & ý định =

Và gây ra ứng dụng web để không xác thực. Bạn có bất kỳ ý tưởng tại sao các giá trị đầu vào không được chuyển đến đối tượng trạng thái sao lưu (mô hình?) Của React?

Trả lời

1

Biểu mẫu đăng nhập thực sự nằm trong iFrame, điều này khiến mọi việc trở nên phức tạp hơn một chút. Tôi đã có thể gửi thành công một thông tin đăng nhập chạy mã sau đây từ bảng điều khiển chrome. Tôi đang sử dụng TestUtils của phản ứng, nhưng bạn có thể sử dụng tốt với bản mô tả:

// run in Chrome console 
var frame = document.querySelector('iframe[src*="login"]'); 
var s = document.createElement('script'); 
var username = frame.contentDocument.querySelector('input[name="username"]'); 
var password = frame.contentDocument.querySelector('input[name="password"]'); 
s.src = "https://fb.me/react-with-addons-0.12.0.js"; 
frame.contentDocument.body.appendChild(s); 

// wait for the script request to resolve and use: 
change = frame.contentWindow.React.addons.TestUtils.Simulate.change; 
change(username, {target: {value: 'My Great Username'}}); 
change(password, {target: {value: 'securepassword'}}); 

nền

Phản ứng sử dụng hệ thống sự kiện ảo riêng của mình, và thường sử dụng controlled components, trong đó chủ yếu là các đầu vào value được thiết lập bằng cách phản ứng và giải thích phần tử DOM. Với ý nghĩ đó, tôi tin rằng vấn đề bạn đang gặp là vì phản ứng tìm kiếm một sự kiện quan trọng trên đầu vào và sử dụng giá trị của đầu vào tại thời điểm sự kiện để đặt giá trị của phần tử DOM. Vì bạn chỉ đang thiết lập thuộc tính value của phần tử DOM, nên bạn đang thoát ra khỏi chu kỳ thành phần được kiểm soát.

Tôi đã cố gắng nhanh chóng gửi một số KeyboardEvent vào đầu vào, nhưng đó là, than ôi, không thành công. Tôi sẽ cập nhật câu trả lời của mình nếu tôi thực sự thành công.

không thỏa đáng workaround:

Sử dụng casper/phantomjs để tự động hóa hình thức điền. Điều này có nghĩa là bạn không phải lo lắng về việc tự mình gửi đi các sự kiện và bạn chỉ có thể để cho "trình duyệt" làm điều đó cho bạn. Nó cũng tốt hơn so với làm việc trong giao diện điều khiển bằng tay.

+0

Như tôi đã nhận xét về câu trả lời khác, tôi đã sử dụng jquery.autotype mà thực tế bắn tất cả các các sự kiện cần thiết và cố gắng mô phỏng hành vi của người dùng gõ các chữ cái nhưng tôi vẫn không thể làm cho nó hoạt động. Tôi cần giải quyết vấn đề này trong bối cảnh JS vì tôi đang tự động hóa trình bao bọc chrome của bên thứ ba mà tôi chỉ có thể kiểm soát thông qua mã JS. – huseyint

+0

@huseyint để có vẻ như biểu mẫu nằm trong iFrame. Tôi đã cập nhật mã của mình bằng một hack rất hack mà tôi đã có thể gửi biểu mẫu thành công; nó có lẽ sẽ không hoàn thành những gì bạn muốn làm programatically, nhưng đó là một sự khởi đầu :) –

+0

lol, nhờ nỗ lực nhưng tôi đang tìm kiếm một giải pháp JS thuần túy :) – huseyint

5

Instagram đang sử dụng phương pháp linkState từ ReactLink:

http://facebook.github.io/react/docs/two-way-binding-helpers.html

Các liên kết trang đăng nhập vào một bundles/Login.js có chứa mã nén như thế này:

o.createElement("input", { 
    className:"lfFieldInput", 
    type:"text", 
    name:"username", 
    maxLength:30, 
    autoCapitalize:!1, 
    autoCorrect:!1, 
    valueLink:this.linkState("username") 
})) 

Nếu bạn nhìn vào các tài liệu cho ReactLink, điều này có nghĩa là giá trị trường đầu vào chỉ được gửi trở lại trạng thái khi sự kiện thay đổi kích hoạt trên các trường nhập. Tuy nhiên, nó không đơn giản như việc kích hoạt sự kiện thay đổi trên nút đang được đề cập đến - tôi nghĩ do cách mà React bình thường hóa các sự kiện trình duyệt. Các Phản ứng tài liệu đặc biệt nói rằng onChange trong Phản ứng không phải là chính xác giống như onChange trong trình duyệt vì nhiều lý do:

http://facebook.github.io/react/docs/dom-differences.html

May mắn thay trong trường hợp bạn đang sử dụng Instagram Phản ứng với Addons bao gồm trong đó cung cấp cho bạn truy cập vào Phản ứng TestUtils, vì vậy bạn có thể làm:

var frm = window.frames[1].document.forms[0]; 
var fReact = window.frames[1].React; 
fReact.addons.TestUtils.Simulate.change(frm.elements[0], {target: {value: 'qacitester' }}); 
fReact.addons.TestUtils.Simulate.change(frm.elements[1], {target: {value: 'qatester' }}); 
frm.elements[2].click(); 

Nhiều tài liệu ở đây:

http://facebook.github.io/react/docs/test-utils.html

Lưu ý rằng vì biểu mẫu đăng nhập nằm trong khung nội tuyến, bạn phải sử dụng thể hiện Phản hồi từ iframe đó nếu không TestUtils sẽ không thể tìm thấy các nút chính xác.

Điều này sẽ chỉ hoạt động trong các trường hợp trong đó React Addons được đưa vào trang. Việc xây dựng React bình thường không phải Addons sẽ yêu cầu một giải pháp khác. Tuy nhiên, nếu bạn đang nói cụ thể về ReactLink thì đó là một addon, do đó, nó không phải là một vấn đề.

+0

Tôi đã thực sự sử dụng jquery.autotype (https://github.com/mmonteleone/jquery.autotype) để điền vào các yếu tố đầu vào nhưng vẫn không có súc sắc. http://screencast.com/t/gfhWW4rD3R – huseyint

+0

Sự kiện 'thay đổi' sẽ chỉ kích hoạt nếu trường tăng sau đó mất tiêu điểm (mờ) * và * giá trị thay đổi ở giữa. Do đó, nếu bạn làm bất kỳ hình thức điền tự động nào không tập trung và làm mờ, nó vẫn không hoạt động. –

+0

Tôi đã chỉnh sửa nhận xét của mình bằng giải pháp hoạt động mà không cần thêm thư viện. –

4

Trả lời câu hỏi của riêng tôi, sự kiện yêu cầu là đầu vào sự kiện có vẻ như và mã này hoạt động:

var doc = window.frames[1].document; 
var frm = doc.forms[0]; 
frm.elements[0].value = 'qacitester'; 
var evt = doc.createEvent('UIEvent'); 
evt.initUIEvent('input', true, false); 
frm.elements[0].dispatchEvent(evt); 
frm.elements[1].value = 'qatester'; 
frm.elements[1].dispatchEvent(evt); 
frm.elements[2].click(); 
Các vấn đề liên quan