wdt reset cause:4, boot mode:(3,6)
You're calling delay() in the onWsEvent() callback. The ESPAsyncWebServer documentation specifically says not to do that in the 'Important things to remember' section:

You can not use yield or delay or any function that uses them inside the callbacks

When you call delay() or loop inside an async web server callback, you block its event task from doing any other processing. This can interfere with a variety of housekeeping functions that HTTP, TCP and the Arduino Core need to perform. In general you should do as little as possible during a callback and return as quickly as possible.
The correct way to structure this code is to set a flag in the callback and inspection the flag and do the work in loop().
For instance,
AsyncWebServer server(80);
AsyncWebSocket ws(&quot;/test&quot;);

boolean flag_move_stepper = false;

void setup(){

and
void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){
 
  if(type == WS_EVT_CONNECT){
 
    Serial.println(&quot;Websocket client connection received&quot;);
 
  } else if(type == WS_EVT_DISCONNECT){
    Serial.println(&quot;Client disconnected&quot;);
 
  } else if(type == WS_EVT_DATA){
    flag_move_stepper = true;

    // you'll need to rewrite this code to share variables with `loop()` and do the work there

and
void loop(){
  if(flag_move_stepper) {
    flag_move_stepper = false;

    // do the work formerly in onWsEvent() here
  }

}

You'll need to make the variables you stored data in in the event handler available to loop() and move the stepper code there for this to work.