-1

I'm trying to find a way to input the receipt number and click the 'Check Status' button on this website: https://egov.uscis.gov/

I can successfully enter a receipt number:

document.getElementById('receipt_number').value = '\(receiptNumber)';

But the 'Check Status' button remains disabled. I can enable the button with:

document.getElementsByName('initCaseSearch')[0].removeAttribute("disabled");

But even with it enabled I still can't click it (errors as 'undefined'). It looks like the webpage has some additional logic or validation that prevents automated form submission, so I tried:

document.forms[0].submit();

But it just reloads the page and doesn't take the input receipt number.

Any ideas?

FlatDog
  • 2,685
  • 2
  • 16
  • 19
  • Setting a value via JS doesn't trigger a change event, the site probably hasn't rerun some required validation. – DBS Jul 03 '23 at 10:52
  • @DBS is there a way to trigger the change event programmatically? – FlatDog Jul 03 '23 at 10:56
  • 1
    [How can I trigger an onchange event manually?](https://stackoverflow.com/questions/2856513/how-can-i-trigger-an-onchange-event-manually) – DBS Jul 03 '23 at 10:56

1 Answers1

0

I dont know about evaluateJS But As far as I searched , Since the website is using ReactJS app, you can't do anything like that using evaluateJS. You should consider using WKScriptMessageHandler to do that.

The way to do that in browser is like this :

const element = document.querySelector("input#receipt_number");
const propertyNames = Object.keys(element);

let reactProps;
for (const propName of propertyNames) {
  if (propName.startsWith('__reactProps$')) {
    reactProps = propName;
    break;
  }
}

if (reactProps) {
  const onChangeHandler = element[reactProps]?.onChange;

  if (typeof onChangeHandler === 'function') {
    const event = {
      target: {
        value: "abc1234567891", // enter your custom values here
      },
    };

    onChangeHandler.call(element, event);

    const buttonElement = document.querySelector("button[type='submit']");
    if (buttonElement && buttonElement[reactProps]?.onClick) {
      buttonElement[reactProps].onClick({preventDefault:()=>{}});
    }
  }
}

I should remind you to replace the value with desired value and change code according to your needs.

**Update : **

Sample Recommended Code to do it with WKScriptMessageHandler :

import WebKit

class MyScriptMessageHandler: NSObject, WKScriptMessageHandler {
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        // Handle the message received from JavaScript
        if let messageBody = message.body as? String {
            // Perform actions based on the message content
            if messageBody == "triggerEvent" {
                // Trigger React event or modify component state here
                if let element = webView.evaluateJavaScript("document.querySelector(\"input#receipt_number\")") as? WKScriptValue,
                   let reactProps = (element.propertyNames.first { $0.hasPrefix("__reactProps$") }) as? String,
                   let onChangeHandler = element.valueForKey(reactProps + ".onChange") as? WKScriptValue {
                    let event = webView.evaluateJavaScript("new Event('change')") as? WKScriptValue
                    onChangeHandler.call(withArguments: [event])
                }

                if let buttonElement = webView.evaluateJavaScript("document.querySelector(\"button[type='submit']\")") as? WKScriptValue,
                   let reactProps = (buttonElement.propertyNames.first { $0.hasPrefix("__reactProps$") }) as? String,
                   let onClickHandler = buttonElement.valueForKey(reactProps + ".onClick") as? WKScriptValue {
                    onClickHandler.call()
                }
            }
        }
    }
}

// Create the WKWebView configuration
let webConfiguration = WKWebViewConfiguration()

// Create an instance of your custom script message handler
let scriptMessageHandler = MyScriptMessageHandler()

// Add the script message handler to the user content controller
webConfiguration.userContentController.add(scriptMessageHandler, name: "myMessageHandler")

// Create the WKWebView with the configuration
let webView = WKWebView(frame: .zero, configuration: webConfiguration)

// Inject the JavaScript code into the WKWebView
let javascriptCode = """
// Add an event listener to trigger the message to the native code
document.querySelector("button").addEventListener("click", function() {
    window.webkit.messageHandlers.myMessageHandler.postMessage("triggerEvent");
});
"""

let userScript = WKUserScript(source: javascriptCode, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
webView.configuration.userContentController.addUserScript(userScript)

// Load your desired URL in the WKWebView
if let url = URL(string: "https://egov.uscis.gov/") {
    let request = URLRequest(url: url)
    webView.load(request)
}

Caution : Do not use this code for automation that might hurt validation process of site or doing illegal things.