Automating a typing test is easy. Making a machine type like someone who actually makes mistakes? That's where things get interesting.

A few days ago, I had a ridiculous thought.

What if I could build a Python program that types faster than almost everyone I know?

Not an AI that writes essays.

Not another ChatGPT wrapper.

Just a simple bot that opens a typing test, reads the text, and starts typing.

No fingers. No fancy mechanical keyboard. No late-night practice sessions.

Just Python.

The first version was almost embarrassingly easy. Give the program some text, tell it where to type, and let the computer do the rest.

It could theoretically produce hundreds of words per minute.

But then I started thinking.

A program typing at an impossibly consistent speed isn't particularly interesting.

What if it occasionally hesitated?

What if it made spelling mistakes?

What if it typed familiar words quickly but slowed down on difficult ones?

Could we make a typing bot that behaves more like an actual human?

That's the experiment we're going to build.

And along the way, we'll learn a few useful things about Python, browser automation, timing, and why typing speed is more complicated than it looks.

First, Why Automate a Typing Test?

Let's address the obvious question.

Why would anyone automate something designed to measure human typing ability?

Fair question.

If your goal is to improve your real typing speed, using a bot to generate an impressive score accomplishes absolutely nothing.

Your keyboard skills remain exactly the same.

But as a programming experiment, typing automation is surprisingly interesting.

It combines several concepts that developers regularly encounter in real projects:

Browser interaction and automation

Keyboard event simulation

Timing and delays

Randomized behavior

Performance measurement

Basic human-behavior modeling

These concepts apply to automated testing, accessibility experiments, user-interface research, and software quality assurance.

We'll build our experiment on a local typing-test page rather than manipulate scores on a public leaderboard.

That keeps the project focused on learning how browser automation works.

And it means we can experiment as much as we want without affecting anyone else's results.

Step 1: Give Python Control of a Browser

We'll use Playwright.

If you've never used it, Playwright is a browser automation framework that allows code to interact with websites.

It can open pages, click buttons, fill forms, simulate keyboard activity, and inspect content.

It's commonly used for testing web applications.

Install it using:

pip install playwright
python -m playwright install chromium

Now create a Python file called typing_bot.py.

Let's start with something simple:

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()

page.set_content(""" <h2>Python Typing Experiment</h2> <textarea id="typing-box" rows="6" cols="60"></textarea> """) page.locator("#typing-box").click() page.keyboard.type("Hello from Python!") input("Press Enter to close...") browser.close() 

Run the file.

A browser window opens with a text area.

Without touching your keyboard, the program types:

Hello from Python!

That's it.

We've just automated keyboard input.

Admittedly, the result isn't particularly impressive yet.

But we now have the foundation for something more interesting.

Step 2: Make the Bot Type at a Specific Speed

A computer doesn't naturally type like a person.

If you give it a string and ask it to enter the characters immediately, it can complete the task extremely quickly.

That makes its typing performance almost meaningless.

Instead, let's control how long it waits between characters.

Typing speed is commonly measured in words per minute, or WPM.

For standardized measurements, a word is often treated as five characters, including spaces and punctuation.

That gives us a simple formula:

Delay per character = 60 / (WPM × 5)

At 60 WPM, the average interval is approximately 0.2 seconds per character.

At 120 WPM, it's approximately 0.1 seconds.

At 200 WPM, it's approximately 0.06 seconds.

We can translate this into Python.

import time

def type_at_speed(page, text, wpm):
delay = 60 / (wpm * 5)

for character in text: page.keyboard.type(character) time.sleep(delay) 

Now our bot can target different speeds.

sample = "Python makes browser automation fun."

type_at_speed(page, sample, 200)

The bot attempts to type at 200 WPM.

Well, approximately.

There's an important detail here: browser automation and Python execution also take time.

Every keyboard call has some overhead, so the final measured speed may differ from the requested speed.

That's a useful reminder that simulated performance and measured performance aren't always identical.

If we wanted more accurate timing, we'd need to measure elapsed time and account for the overhead.

For this experiment, though, our simple delay model is enough to demonstrate the concept.

Step 3: Make It Less Perfect

Here's where the project gets interesting.

Real people don't type with mathematically perfect timing.

Sometimes we pause.

Sometimes our fingers move quickly through familiar words.

Sometimes we hesitate before punctuation or unfamiliar combinations.

Our first bot doesn't do any of that.

It enters every character using approximately the same delay.

That makes its behavior extremely predictable.

Let's introduce randomness.

import random
import time

def type_naturally(page, text, wpm=80):
base_delay = 60 / (wpm * 5)

for character in text: variation = random.uniform(0.75, 1.25) delay = base_delay * variation if character in ".,!?": delay += random.uniform(0.1, 0.3) time.sleep(delay) page.keyboard.type(character) 

Now our bot behaves a little differently on every run.

Some characters arrive faster.

Others arrive slower.

Punctuation introduces an occasional pause.

It's still not a realistic model of human motor behavior, but it no longer produces perfectly uniform timing.

And that distinction matters.

A machine can imitate certain observable characteristics of human activity without actually reproducing the mental and physical processes behind it.

We're modeling timing patterns, not building a genuine digital typist.

Step 4: Add Something Every Human Understands — Typos

Nobody types perfectly all the time.

Even experienced typists make mistakes.

Sometimes they hit a neighboring key.

Sometimes they enter the same character twice.

And sometimes their fingers seem to invent an entirely new spelling.

Let's make our bot occasionally do the same thing.

def type_with_mistakes(page, text, wpm=80):
base_delay = 60 / (wpm * 5)

for character in text: time.sleep(base_delay) if ( character.isalpha() and random.random() < 0.03 ): wrong_key = random.choice("abcdefghijklmnopqrstuvwxyz") page.keyboard.type(wrong_key) time.sleep(0.15) page.keyboard.press("Backspace") time.sleep(0.1) page.keyboard.type(character) 

Now there's roughly a 3% probability of an intentional mistake before each alphabetic character.

When that happens, the bot enters an incorrect letter, briefly pauses, deletes it, and types the intended character.

The result is much more entertaining to watch.

Instead of flawlessly producing text, our program occasionally stumbles and corrects itself.

But here's something worth noticing.

Those mistakes consume time.

So even if we configure the bot's basic character delay for 80 WPM, its actual completed-text speed will be lower once corrections are included.

That's exactly why typing speed and typing accuracy are closely related.

Step 5: Measure the Bot Instead of Trusting It

It's easy to tell a program to type at 100 WPM.

It's another thing to verify that it actually achieves that speed.

Let's measure the elapsed time.

start = time.perf_counter()

type_with_mistakes(page, sample, wpm=80)

elapsed = time.perf_counter() - start

actual_wpm = (len(sample) / 5) / (elapsed / 60)

print(f"Time taken: {elapsed:.2f} seconds")
print(f"Measured speed: {actual_wpm:.1f} WPM")

Now we have a measurable result.

The calculated WPM uses the final text length and total elapsed time, including corrections.

This isn't a complete typing-test scoring system. It doesn't separately report gross speed, uncorrected errors, or accuracy.

But it's a reasonable starting point.

We can experiment with different delays, typo probabilities, and punctuation pauses to see how they affect the final speed.

And unlike simply assigning the bot a target WPM, we're measuring what happened.

Step 6: Compare the Machine With Yourself

Now comes the interesting part: finding out how your actual typing ability compares with a Python script.

Before running another automated experiment, try taking an online typing speed test to measure your words per minute (WPM) and typing accuracy.

Type naturally. Don't rush to beat a particular score, and don't worry if you make a few mistakes.

Once you've finished, compare your results with the bot's performance.

You'll probably notice something interesting. Your speed changes depending on the words, punctuation, and how comfortable you feel with the keyboard. You might fly through familiar sentences but slow down when you encounter unusual letter combinations.

Our Python bot doesn't experience any of that naturally. It follows programmed delays and simulated mistakes.

And that's what makes the comparison interesting.

A typing test measures your speed, but understanding why that speed changes tells you much more about your actual typing skills.

For a person trying to improve their keyboard ability, consistency, accuracy, and honest measurement matter much more than producing an enormous number.

What This Experiment Actually Teaches Us

We started with a simple idea.

Make Python type faster than a human.

Then we made it slower.

Then we introduced random pauses.

Then we deliberately made it commit mistakes.

And suddenly, the project became more interesting than a speed contest.

We began exploring the difference between automation and behavior.

That difference appears throughout software engineering.

A test script can click a button.

But that doesn't mean it understands why a user clicks it.

An automated agent can fill out a form.

But that doesn't mean it knows whether the form is confusing.

A program can generate realistic-looking activity.

But that doesn't automatically make the underlying experience realistic.

This is why automated testing is most useful when developers understand what they're trying to validate.

A typing bot can test whether a text field receives input correctly.

It can help investigate timing behavior.

It can reproduce certain input sequences.

But it cannot replace genuine human evaluation of how comfortable or intuitive a typing interface feels.

Those are different kinds of testing.

And good developers know when to use each one.

Could We Take This Project Further?

Absolutely.

Our current bot is intentionally simple.

A more advanced version could include a small local dashboard displaying target WPM, measured WPM, typing duration, and correction count.

We could create multiple simulated typing profiles.

One could imitate a careful beginner, using slower character intervals and frequent corrections.

Another could imitate an experienced typist with steadier pacing.

A third could emphasize short bursts of speed followed by occasional pauses.

We could also experiment with realistic error models.

Instead of choosing a completely random incorrect letter, the bot could use neighboring keys from the QWERTY keyboard layout.

For example, accidentally pressing r instead of t is more physically plausible than accidentally pressing z instead of t.

That would make our typo simulation more meaningful.

We could measure how much time each correction adds, how typing speed changes across longer passages, and which timing patterns produce the greatest variation.

For legitimate browser testing, these experiments could help developers evaluate text-entry components under different input conditions.

Just remember that randomizing delays isn't the same as accurately simulating a human.

It's a simplified model.

And simplified models are useful precisely when we understand their limitations.

The Funny Thing About Making Computers Type Like Humans

There's something almost backwards about this entire experiment.

Computers were created to help us perform tasks more efficiently.

Now we're deliberately slowing one down so it behaves more like us.

We're adding hesitation.

Introducing mistakes.

Making it pause at punctuation.

And spending time designing errors a computer would never naturally need to make.

But those imperfections are what make the experiment worth exploring.

A bot that produces 500 WPM with no mistakes is predictable.

A bot with variable timing and occasional corrections gives us something to investigate.

Not because it has become human.

But because studying the differences helps us understand both software automation and human behavior a little better.

And that's one of the things I enjoy most about programming.

You can start with a silly question and end up learning something genuinely useful.

Final Thoughts: The Bot Won, but It Didn't Really Win

Our Python bot can enter text at speeds that would be difficult for most people to sustain.

It doesn't need typing lessons.

It doesn't care which keyboard is attached.

It doesn't need to remember where the keys are.

And it never gets tired.

But none of that makes it a better typist in the human sense.

It's an automation script doing what it was programmed to do.

The interesting achievement isn't the simulated WPM.

It's understanding how to control browser input, model timing, introduce uncertainty, and measure results.

That's what turns a small coding trick into an actual programming exercise.

And if the experiment inspires you to test your own typing speed afterward, that's a bonus.

Because there's one thing our bot won't gain from all this practice.

An actual skill.

The computer can imitate typing. You're the one who can learn to do it better.

Let that sink in.

Further Reading and Useful Resources

Playwright for Python — Official documentation covering browser automation, keyboard input, and testing.

Python's time Module — Timing functions, including sleep() and perf_counter().

Python's random Module — Tools for adding controlled randomness to programs.

Check My WPM — Practice and measure real typing speed and accuracy.

Python Documentation — A reference for understanding and extending the example programs.

The best programming experiments don't always begin with serious problems. Sometimes they start with asking whether Python can win a typing test.