subscribe by email and YouTube to get notification of new posts. & videos.

Human Emulation Scroll

To be a litle more difficult, cause, in emulating cursor (previous article) the target website (so youtube) does not know if any code was injected (as no one code was injected) cause the Bot app emulate the cursor, easy, but, in scrolling, some sources says to use , where N = bla bla

browser.ExecuteScriptAsync("window.scroll(0,N);");

but , say to IA «can js detect browser.ExecuteScriptAsync»

results in

JavaScript cannot directly detect the execution of a browser.ExecuteScriptAsync call because this method is part of the host application’s API (such as WebView2 or CefSharp) and operates outside the standard JavaScript environment. 

However, a script can indirectly detect its own injection or «presence» using the following methods:

1. Self-Identification via State

If the host application uses ExecuteScriptAsync to set a global variable, standard JavaScript can check for that variable’s existence. 

  • Detection logic: if (window.myInjectionFlag) { ... }

2. Monitoring DOM or Event Changes

Since ExecuteScriptAsync is often used to modify the DOM or trigger events, JavaScript can use a MutationObserver to watch for unexpected changes that did not originate from the page’s original scripts. 

3. Stack Trace Analysis

In some environments, if a script is executed via an external command, the Error().stack property might reveal a unique trace (e.g., <anonymous> or specific internal wrappers), though this is highly implementation-specific and unreliable for robust detection. 

4. Communication Back to Host

The most common way for JavaScript to «acknowledge» an external script execution is to use host-provided bridges like:

  • WebView2: window.chrome.webview.postMessage().
  • CefSharp: CefSharp.PostMessage() or bound objects. 

For more details on implementing these interfaces, see the official documentation for WebView2 APIs or the CefSharp WebBrowserExtensions

so, 2 things

May my app can use a non injected script, say to scrollgthe browser instance ? if not, then ooohh need to test

So I ask the following (while listen to Im looking at gthe windows Stieve vai):

can js detect is u use oin winformn a webview2 with Document.Window.ScrollTo(0, 0) ?

which results in:

In 2026, JavaScript running inside a WebView2 control can detect the fact that a scroll occurred, but it cannot inherently distinguish whether that scroll was caused by a WinForms Document.Window.ScrollTo(0, 0) command or a user’s manual action. 

How JS Detects the Scroll

  • The scroll Event: Whenever the scroll position changes—whether programmatically via C# or manually by a user—the JavaScript scroll event fires.
  • The scrollend Event: Modern browsers (including the Edge/Chromium engine used by WebView2) support scrollend, which fires when any scroll animation completes. 

SO, js , so youtube, cannot detect using this last method, if our app is a bot or not, so OK, camon men

So code, to record a human real scrolls, to put on database

UNFORTUNATELY, WebView2 does not allow to scroll without injecting JS, and the old WebBrowser does, but it is not supported on loading many websites, including youtube, that they reject tyo show, if this old browser is used.


So, 2 opcions, use other control or scroll by moving the mouse (not emulating the scroll wheel), eyy eyyy, wait a moment, am I said Scroll wheel ??? let me checkl if I can control mouse scroll wheel ??

I’ve got this code

Imports System.Runtime.InteropServices

Public Class Form1
    Private WithEvents Tmr As New Timer With {.Interval = 2000}

    Private Const MOUSEEVENTF_WHEEL As Integer = &H800 'The amount of movement is specified in mouseData.
    Private Const MOUSEEVENTF_HWHEEL As Integer = &H1000 'Not available for 2000 or XP

    <DllImport("user32.dll", EntryPoint:="mouse_event")> _
    Private Shared Sub mouse_event(ByVal dwFlags As UInteger, ByVal dx As Integer, ByVal dy As Integer, ByVal dwData As Integer, ByVal dwExtraInfo As UInteger)
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.KeyPreview = True
        Tmr.Start()
    End Sub

    Private Sub Tmr_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Tmr.Tick
        MouseScroll(False, 10) 'scrolls Down 10 wheel clicks
        'MouseScroll(True, 1) 'scrolls Up 1 wheel click
    End Sub

    Private Sub MouseScroll(ByVal up As Boolean, ByVal clicks As Integer)
        If up Then
            mouse_event(MOUSEEVENTF_WHEEL, 0, 0, (clicks * 120), 0)
        Else
            mouse_event(MOUSEEVENTF_WHEEL, 0, 0, -(clicks * 120), 0)
        End If
    End Sub
End Class

Does it work ?

And now, how can I record a human natural scroll ? to later port to playback ?

YES, in winforms, there’s the _MouseWheel Event

say

Private Sub WebView2_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseWheel

e.delta 

End Sub

So I need to make my own recorder / playback for

ERROR: On the VB.bnet applicartion seems that the event handler of WebView2.MouseWheel is not fired, oops

Victor

Unfortunately, the current latest version of the WebView2 1.0.674-prerelease don’t support MouseWhell events too. If is possible to download and run examples from https://github.com/MicrosoftEdge/WebView2Samples.

Hey its get fired but with no url loaded

Lets see over the entire form, no it does not work, soo

We have a problem MIKE

Well not at all, as the Winform allows (yes) to catch the e.delta on scrolls, thaen I can record like if i was on the webview2, just to grab some human movements, them the question is

Will I be able to apply those recorded events (scroll) on the webview2, lets see

YESSSSSS, DONEEE

It was a litle bit trciky, cause, hmnn let me show the code used

following is the unfinished code, but does what it is needed, so to get actions based on 10 ms timer, to get 0 = no scroll, +120 = scrollup or -120 = scroll down

VB.NET Winforms 4.7 CODE

#Region "Imports"
Imports System.Security.Policy
Imports Microsoft.Web.WebView2.WinForms
Imports System.Runtime.InteropServices
Imports System.Runtime.CompilerServices 'Required to load low level Win DLL's
#End Region
Public Class ScrollRecPlay
#Region "OS DLL"
    Private Const MOUSEEVENTF_WHEEL As Integer = &H800 'The amount of movement is specified in mouseData.
    Private Const MOUSEEVENTF_HWHEEL As Integer = &H1000 'Not available for 2000 or XP
    <DllImport("user32.dll", EntryPoint:="mouse_event")>
    Private Shared Sub mouse_event(ByVal dwFlags As UInteger, ByVal dx As Integer, ByVal dy As Integer, ByVal dwData As Integer, ByVal dwExtraInfo As UInteger)
    End Sub
#End Region
#Region "Variables"
    Private WithEvents TiRec As New Timer With {.Interval = 50} : Private WithEvents TiPlay As New Timer With {.Interval = 50}
    Private LastScrollDelta As Integer
#End Region
#Region "Buttons"
    Private Sub btnLoad_Click(sender As Object, e As EventArgs) Handles btnLoad.Click
        WebView21.Source = New Uri(txtUrl.Text)
    End Sub
    Private Sub btnRec_Click(sender As Object, e As EventArgs) Handles btnRec.Click
        TxtValues.Text = ""
        btnRec.Enabled = False : BtnStop.Enabled = True
        TiRec.Enabled = True
    End Sub
    Private Sub BtnStop_Click(sender As Object, e As EventArgs) Handles BtnStop.Click
        btnRec.Enabled = True : btnPlay.Enabled = True : TiRec.Enabled = False
    End Sub
    Private Sub btnPlay_Click(sender As Object, e As EventArgs) Handles btnPlay.Click
        'mouse_event(MOUSEEVENTF_WHEEL, 0, 0, (clicks * 120), 0)
        Me.Text = "Be Sure "
        btnPlay.Enabled = False
        TiPlay.Enabled = True

    End Sub
#End Region
#Region "Timers"
    Private Sub TiRec_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles TiRec.Tick
        TxtValues.Text = TxtValues.Text & "," & LastScrollDelta
        LastScrollDelta = 0
    End Sub
    Private Sub TiPlay_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles TiPlay.Tick
        MouseScroll(False, 100)
        Me.Text = "done"
    End Sub
#End Region
#Region "WebView2"

#End Region
#Region "Functions"
    Private Sub MouseScroll(ByVal up As Boolean, ByVal clicks As Integer)
        If up Then
            mouse_event(MOUSEEVENTF_WHEEL, 0, 0, (clicks * 120), 0)
        Else
            mouse_event(MOUSEEVENTF_WHEEL, 0, 0, -(clicks * 120), 0)
        End If
    End Sub

#End Region


    Private Sub ScrollRecPlay_MouseWheel(sender As Object, e As MouseEventArgs) Handles Me.MouseWheel
        If Not btnPlay.Enabled = False Then 'to not get fired if playback (which will call to scroll)
            LastScrollDelta = e.Delta
        End If

    End Sub



End Class

Note: the minimum effective interval is at 50 ms, so a bit far from those 10 ms but it should be ok, I think.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Comentarios

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *