0% found this document useful (0 votes)
331 views

Hacking Java Script Short

Uploaded by

Nenad Petrövic
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
331 views

Hacking Java Script Short

Uploaded by

Nenad Petrövic
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 67

Hacking JavaScript

Just Enough JavaScript To Make You Dangerous

Alan Richardson

EvilTester.com
EvilTester.com Hacking JavaScript

Copyright © 2021 Alan Richardson, Compendium Developments Ltd. All rights reserved.

2 Alan Richardson
Contents

Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Hacking JavaScript Apps and Games . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Why? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Played vs Played With . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Microcosm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Practicing Using JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Free Video Discussing This Topic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Some Notes on Bot Creation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Want to see my XType bot in action? . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Example Bot Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Testing Evil Tester Sloganizer From the JavaScript Console . . . . . . . . . . . . . . . . . . 16
JavaScript HTML Element Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
onclick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Exercise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Look at the source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Exercise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Interacting with applications from the console . . . . . . . . . . . . . . . . . . . . . . 19
Call functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
for loops and console.log . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Interacting with the sloganizer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Advanced Techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
setInterval . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Hack the Sloganizer to create your own slogans . . . . . . . . . . . . . . . . . . . . . 24
Using the existing structures: . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Using New Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Practical application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

3
EvilTester.com Hacking JavaScript

Some Exercise Answers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26


Generate a random sentence using a sentences template . . . . . . . . . . 26
Generate 100 random sentences from a specific template . . . . . . . . . . . . 27
Generate 1000 random sentences . . . . . . . . . . . . . . . . . . . . . . . . . 27
Case Study - A Link Checker In The JavaScript Console . . . . . . . . . . . . . . . . . . . . . 28
External Link Checkers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Building a Link Checker . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Find all the links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Checking Links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Simple link checker using XMLHttpRequest . . . . . . . . . . . . . . . . . . . . . . . . 30
Using Fetch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Could I check status for these? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
What else could fetch do? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
My final code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Not an everyday link checker . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
History of Game Of Life . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Programs to download, install and experiment with: . . . . . . . . . . . . . . . . . . . 36
online games of life: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Cellular Automata Life Game Suitable for Playing . . . . . . . . . . . . . . . . 36
Cellular Automata Life Game Suitable for Hacking . . . . . . . . . . . . . . . . 36
Related References: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Recommended Books . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Investigate the Invasion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
An Invasion Challenge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
First control the invasion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Create a Glider . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
But an invasion should be random . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Watch The Video . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Change Colour of Cellular Entity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Colour in the Game . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Change colour by debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Change colour from console when runnning game . . . . . . . . . . . . . . . . . . . . 40
Watch The Video For Colour Change . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Change Colour Automatically . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Random Hex Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Randomly set the colour every second . . . . . . . . . . . . . . . . . . . . . . 42
Make Bot Faster or Slower . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

4 Alan Richardson
Hacking JavaScript EvilTester.com

Cycle over all the colours . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43


Watch The Video for Automatic Colour Change . . . . . . . . . . . . . . . . . . . . . . 43
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Change World Size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Scouting for Clues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Let’s Change the World . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Change the Speed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Watch The Video . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Create a Random World . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Stop and Clear the Game . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Randomly generate stuff . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Experiment and Watch the Video . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Other Ways To Use These Skills . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Bookmarklets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Starting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Resources: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Tools to create bookmarklets . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Writing Chrome Extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Also . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Appendices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Practice Apps To Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Testing Apps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Todo App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Tips for Learning JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
How does learning JavaScript help? . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Any Resources? If you are a tester and want to learn JavaScript. . . . . . . . . . . . . . 54
Tip 1. . . Automating in the Browser . . . . . . . . . . . . . . . . . . . . . . . . 54
Tip 2. . . Eloquent JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Tip 3. . . JavaScript Enlightenment . . . . . . . . . . . . . . . . . . . . . . . . 54
Tip 4. . . Speaking JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Tip 5. . . DOM Elightenment . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Tip 6. . . JavaScript Design Patterns . . . . . . . . . . . . . . . . . . . . . . . . 55
Tip 7. . . Support Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Tip 8. . . Go Make Things . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Tip 9. . . Useful Snippets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Tip 10. . . JavaScript for Cats . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Tip 11. . . Javascript Weekly . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Tip 12. . . Order to use them . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

Alan Richardson 5
EvilTester.com Hacking JavaScript

Free Video Inside . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57


Just Enough JavaScript To Be Dangerous Reference . . . . . . . . . . . . . . . . . . . . . . 58
Console . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Integers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Hex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Math library/Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Using the Console object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Alerts and Prompts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Iteration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
for Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Position Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Key Indexed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Selection and Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
if statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Run Code Every X milliseconds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Interact with the DOM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Finding Elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Change Style Element Attributes . . . . . . . . . . . . . . . . . . . . . . . . . 63
Change Element Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Change Element Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Changing Event Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Good JavaScript References For Future Study . . . . . . . . . . . . . . . . . . . . . . . . . 65
Tutorials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
JavaScript Hacking Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
General Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
About The Author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

6 Alan Richardson
Hacking JavaScript EvilTester.com

Introduction

Welcome to this short ebook on using JavaScript from the Browser Dev Tools Console.

I initially learned to do this to:

• improve my JavaScript
• hack some online games
• manipulate web applications I was testing

Over time my JavaScript has improved to the point that I now write simple applications in JavaScript
and using Google App Script.

This ebook will provide some tutorial information, reference information and links to practice applica-
tions and learning material.

This is a draft ebook and I will expand it in the future to be a proper book.

I have included two tutorial sections covering:

• how to hack my Evil Tester sloganizer


• how to hack and manipulate my Game of Life applications

Both of these tutorials will have you manipulating a browser application from the console and writing
some JavaScript.

If you want a video tutorial then I have a free online course on “Automating in the Browser Using
JavaScript” hosted on Test Automation U

• testautomationu.applitools.com/automating-in-the-browser-using-javascript

Hope you find it useful.

• Alan Richardson

Copyright Alan Richardson, Compendium Developments Ltd 2021

And if you are serious about improving as a tester and want exclusive daily posts then join the Evil
Tester Patreon Programme and gain access to exclusive posts, videos and courses:

• https://www.patreon.com/eviltester

Alan Richardson 7
EvilTester.com Hacking JavaScript

Hacking JavaScript Apps and Games

By “Hacking a JavaScript Game” I mean:

Manipulating the game or application to do things it was never designed to do. Or automate it
from the JavaScript console and bypass the programmed GUI.

I’ve used this to:

• create simple bots that play games


• automate applications to put them into state ready for exploratory testing
• automate the creation of test data in applications

Why?

‘Hacking’ is a useful concept to trigger our thinking around creative ways to interact or manipulate the
application.

Played vs Played With

When you play a game, you just play it.

When you Play with the game, you go beyond what the game designer intended, you can add much
more value to your education.

Microcosm

A game is a small, highly dynamic, ‘system’.

Very often with the ‘large’ systems that we test:

• we enter data
• which goes to the backend
• and is stored in the database
• and we see some visual indication of that
• the system receives more input from more people
• a batch or collation process kicks off
• we see an update from the server with the collation

8 Alan Richardson
Hacking JavaScript EvilTester.com

And this can take minutes, or hours.

In a game, this takes milliseconds.

All the techniques we use for testing, we can use when ‘hacking’ games, and because the feedback is
so fast, we have to:

• learn the game fast,


• learn the game technology,
• create small, but effective, solutions unique to that game,
• have an array of ‘techniques’ which are generic,
• create data
• understand application state
• manipulate application state
• etc.

All the ‘stuff’ we do when we are testing, we have to do when ‘hacking’ the JavaScript game.

Alan Richardson 9
EvilTester.com Hacking JavaScript

Practicing Using JavaScript

One way I practice my Software Testing, improve my JavaScript programming and practice my au-
tomating is by ‘hacking’ JavaScript games.

One of my bots scored 282010 on https://phoboslab.org/xtype/ This ‘bot’ is JavaScript code that runs
from the Browser Dev Tools and plays the game.

I have a video showing the bot in action below.

To create this I have to learn to use the dev tool to inspect the Dom, and the running memory space,
and read the JavaScript. All of this is modelling the application. A recon step that helps me with my
Software Testing.

As I recon the app I look at the network tab to see what files are loaded and what API calls are issued.
This also informs my model. And makes me think about Injection and Manipulation points.

Perhaps I can use a proxy to trap and amend those requests? Perhaps my proxy can respond with a
different file or data automatically?

These are thought process and skills that I can apply in my testing. I also learn more about HTTP, Dev
tools and Proxies.

When the game is running I have to observe its execution behaviour. I build a model of the software
and its functionality. This informs my Software Testing. I have to build models of the application as I
test and make decisions about what to target.

To ‘hack’ the game, I have to inspect the objects which have been instantiated by the code. I can do
this in the console by typing in the object names.

10 Alan Richardson
Hacking JavaScript EvilTester.com

To learn what these objects are I have to read the game code. This improves my JavaScript because
one of the best ways to learn to write code is to read code and try to understand what it does.

I can use the Snippets view in Chrome Sources to write JavaScript. This is a built in mini JavaScript IDE
in the browser.

Alan Richardson 11
EvilTester.com Hacking JavaScript

I can write simple code here to manipulate the game objects in memory to help me cheat and hack
the game. I don’t need to learn a lot of JavaScript to do this, and most of the JavaScript you need is
already in the game source itself.

To write a ‘bot’... code that executes in its own thread periodically to do something, I use the ‘setInterval’
command. This is the fundamental key to writing JavaScript bots. e.g.

var infiniteLivesBot = setInterval(infiniteLives,1000);

The above line calls a function named infiniteLives every second. That infiniteLives function checks if
my number of lives have decreased, and if so, increase them. e.g.

function infiniteLives(){
if(game.lives<3){
game.lives=3;
}
}

var infiniteLivesBot = setInterval(infiniteLives,1000);

I can easily stop this bot using the clearInterval command.

clearInterval(infiniteLivesBot);

I can run that code from the snippets view, or paste it into the console, or convert it into a bookmarklet.
Whatever is more convenient to help me when I want to hack the game. I do the same thing to support
my testing e.g. setup data, delete data etc.

This is a form of ‘tactical’ automating. It won’t scale, it doesn’t go into continuous integration. It
supports me. It does a specific task. It automates part of my work. It is a good start to learning to
automate more strategically.

To automate xtype I had to learn how to trigger mouse events to initiate the firing functionality. I couldn’t
remember how to do this. I copy and pasted a snippet of code from stackoverflow. All professional
programmers do this.

• stackoverflow.com/questions/2381572/how-can-i-trigger-a-javascript-event-click

var event = document.createEvent("MouseEvents");


event.initEvent("mousedown", true, true);
document.getElementById("canvas").dispatchEvent(event, true);

Part of learning programming is knowing where to find a general answer. Knowing which part of the
answer to isolate. Then having the confidence to bring that into your code and experiment with it.

As I do this, I learn more JavaScript. Which allows me to write scripts in other tools e.g. Postman. And I
can inject code into applications e.g. using WebDriver JavaScriptExecutor. The more I practice, the

12 Alan Richardson
Hacking JavaScript EvilTester.com

more options I open up.

I take the knowledge and then write small utilities or applications to help me. I write a lot of small
JavaScript utilities to help me with data extract activities and reformatting of data from Web applica-
tions.

I extended my knowledge by writing JavaScript applications and games which I bundled into:

• github.com/eviltester/TestingApp
• running here eviltester.github.io/TestingApp

If you want to experiment with simple games manipulation and hacking then the games in this app are
designed for that purpose.

Doing this also has a knock on effect on how I view web applications. The GUI is no longer a trusted
client. The GUI can be manipulated by the user. The messages it sends to the server can be manipulated
by the user. The server needs to be robust.

This helps my Software Testing. I have to go deeper when I test. And by practicing I develop the skills
to go deeper when I test. I can recognise when requirements need to be tested more deeply than they
state on the surface.

This helps my programming. I am very aware that the server needs to validate and approach the input
data with caution.

This is one way that I practice my Software Testing, JavaScript programming and automating. The
benefit to me has been enormous. I recommend this, or adapt the ideas and create your own practice
path.

Free Video Discussing This Topic

• youtu.be/TpCCEEsW4rA

Some Notes on Bot Creation

This was a hard bot to write Xtype is a bullet hell shooter which are challenging to play, let alone
automate - and no, I’m not going to show you the code for the bot.

But this is not my first bot.

I’ve written bots to play z-type, Cookie Clicker, 3D Monster Maze

I like these games because they are all well written, I can read the code to improve my programming,
and they are fun to play.

Alan Richardson 13
EvilTester.com Hacking JavaScript

Many of my bots are not full playing bots like the x-type bot. They are support tools. And when I started
to automate x-type I started with support tools:

• an infinite lives hack


• an auto-aimer so that I didn’t have to keep track of the boss while I was controlling the player
• I added auto firing to the auto-aiming so I only had to concentrate on moving the player
• I combined all three and had a bot that could play the game, although it was cheating with
infinite lives.
• only then did I approach the autonomous playing of the game

For 3D Monster Maze I only wrote support tools:

• a heads up display so that a map of the screen was rendered on screen as I played showing me
the position of Rex to help me avoid him, and showing me where the exit was
• a trap for Rex, so that if he entered it he couldn’t move
• a chain for Rex so that he never moved from his starting point
• armour so that if Rex caught me, he couldn’t kill me

For many games I try to think how to add extra features to make the game more interesting. I don’t
have the skill or patience to write games like these, but I do have the skill and motivation to ‘augment’
them for my learning.

This is analogous to writing ‘tools’ to support our testing, or making applications more ‘testable’.

Note: my games github.com/eviltester/TestingApp are not well written, but they are very easy to
understand and hack.

Want to see my XType bot in action?

• youtu.be/xCN26i0-ees

Example Bot Code

I have a few gist code snippets which are bots, or used to automate applications from the console. You
can find these online:

• https://gist.github.com/eviltester

The first version of the Bot I created for ZType is here:

• gist.github.com/eviltester/076b8e52a9b3c0bb3868a0ec6150c860

14 Alan Richardson
Hacking JavaScript EvilTester.com

And you can find ZType, here:

• https://zty.pe/

var zTypeBotAlphaChars = "abcdefghijklmnopqrstuvwxyz";


var zTypeBotCharToType = 0;
ztypebot = setInterval(function() {
ig.game.shoot(
zTypeBotAlphaChars.charAt(zTypeBotCharToType));
zTypeBotCharToType = (zTypeBotCharToType +1)%26;
}
, 10);

NOTE: The above code differs from the gist in that it runs every 10 milliseconds, the published gist
uses 100 milliseconds.

The above code is very inefficient because is issues a keystroke every 10 milliseconds without knowing
if that letter is valid or will make a difference. I eventually made it much better to make more use the
in memory variables, but it might be a useful place to start when experimenting with your own bots
later.

I recommend working through the rest of this text, and then revisiting this bot later when you have
developed more JavaScript and DOM Analysis skills.

Alan Richardson 15
EvilTester.com Hacking JavaScript

Testing Evil Tester Sloganizer From the JavaScript Console

We will start with the “Evil Tester Sloganizer” as an example to get us used to using JavaScript and
working with the console.

• The Evil Tester Sloganizer


• https://eviltester.github.io/TestingApp/apps/sloganizer/version/1/sloganizer.html

A simple web page with a button which you click, and a new ‘slogan’ appears on screen.

All of this is controlled by JavaScript.

How does it work?

JavaScript HTML Element Events

When we click on the button, an ‘on click’ event is triggered.

The button has an event handler that deals with the event.

In the case of “Evil Tester Sloganizer” the event is coded into the page so you can see the onclick
handler in the code.

<div class="title">
<button class="title" onclick="changeSlogan()">I Want A Slogan</button
>
</div>

Apps don’t always make it so easy, and sometimes the handlers are added dynamically by JavaScript.

We can also see the event handler by using the browser ‘inspect’ functionality.

In the ‘Event Listeners’ tab. On this tab we can also ‘click through’ to see where in the source code the
event is handled.

onclick

onclick="changeSlogan()"

The above code basically says: “call the changeSlogan function”.

We could also do this from the JavaScript Console.

If I open the JavaScript console and type ‘changeSlogan()’ then the slogan will change.

We have effectively run the code behind the button.

16 Alan Richardson
Hacking JavaScript EvilTester.com

Instantly we know that we don’t have to automate this application from the GUI any more. We can
write JavaScript code in the console to interact with the app.

Exercise

• visit The Evil Tester Sloganizer v 1


• inspect the button element
• see that you can view the event in the ‘Elements’ ‘Event Listeners’ tab
• use the JavaScript console to change the slogan by typing ‘changeSlogan()’ at the console

Look at the source

For this application, all the source code is in the loaded HTML page.
We can see it in the <script>...</script> element at the bottom of the page.
If this is the first time you’ve seen JavaScript then it might look complicated but it is pretty simple.
We basically have:

• some objects
• some functions

We are not going to teach you a lot of JavaScript in this section, you’ll have to to research on your own
if you want to learn JavaScript properly.
The aim here is to learn enough JavaScript to start interacting with applications from the console and
manipulate the running state of the application.

• learn enough JavaScript to be dangerous

Objects

The objects are:

• an object called phrases which is a set of phrases, and these ‘phrases’ are arrays
• an object called sentences which is an array of string

Both of these objects (phrases, sentences) are accessible from the JavaScript console.
If I type phrases at the console I will see information about that object in the console

Object {start: Array[4], im_not: Array[8],


i_am: Array[2], o_just: Array[2], just: Array[2]
...
}

Alan Richardson 17
EvilTester.com Hacking JavaScript

And it is an interactive view so I can expand it to see all the ‘keys’ and their values.

If the object has any functions then I’ll see them listed too.

Functions

The functions look like this:

function randomNumberUpTo(theVal){
return Math.floor(Math.random() * theVal)
}

• This is a function
• called randomNumberUpTo
• it takes a single argument theVal
• it uses the JavaScript Match library
• it returns a random number up to the value of theVal

But, we don’t really need to understand the function to know that:

• we can run this function from the console

> randomNumberUpTo(4)
< 1
> randomNumberUpTo(4)
< 2
> randomNumberUpTo(4)
< 0

Every time I enter the function call into the console, the function will be called and it will display the
return value of the function in the console.

Exercise

• Look at the source for the sloganizer and see how much you understand
• type the names of the objects that you see into the console
• explore the output in the console
• run some of the functions that you find
• observe that when you type a function name you have code completion in the console (press
tab to autocomplete a function name)
• if you press the cursor up and down then you can select items from the console history - use this
to re-enter commands

18 Alan Richardson
Hacking JavaScript EvilTester.com

You can learn more about the console in the Chrome developer tools help:

• https://developers.google.com/web/tools/chrome-devtools/debug/console/?hl=en

Interacting with applications from the console

We can use the console to interact with the application.

• Call functions
• Change variables

Call functions

The hardest part about interacting with the application from the console is knowing which functions
to call.

In this app we have low level utility functions like:

• randomNumberUpTo
• removeExtraSpaces
• removeSpacesAtStart
• capitalizeFirstLetter
• removeSpacesBeforePunctuation
• getRandomValueFromArray

Then ‘application’ functions like:

• changeSlogan
• random_sentence
• process_sentence
• expand_text
• getSentence

The reason I have split these into ‘application’ and ‘low level’ is because the ‘low level’ functions
basically just take JavaScript primitives and return values. They could be found in pretty much any
application.

The ‘application’ functions, do ‘stuff’ related to this application.

• changeSlogan calls other functions to generate a random slogan and makes it appear on the
GUI
• random_sentence returns a random sentence filled with random values

Alan Richardson 19
EvilTester.com Hacking JavaScript

• process_sentence given a sentence template it will fill it with values then call all the utility
functions to process the string.
• expand_text does the work of expanding a template
• getSentence calls the utility function to choose a random sentence template

We can ‘test’ the application without clicking the button.

For example, suppose we wanted to make sure that the randomNumberUpTo method really did work,
but we can’t really check that from the GUI.

Since we can call randomNumberUpTo from the console we could run some tests:

• check that randomNumberUpTo(0) only ever returns 0


• check that randomNumberUpTo(1) only ever returns 0
• check that randomNumberUpTo(2) only ever returns 0 or 1

Because this is ‘random’ we would have to keep typing the text in every time we want to run it.

for loops and console.log

Two very important JavaScript commands we will use when interacting from the console are:

• console.log
• for

console.log Using console.log we can print information to the console:

console.log("hello world");

Would print

> console.log("hello world");


hello world
< undefined

• We typed console.log("hello world");


• hello world was printed to the console
• console.log function did not return a value so undefined is printed

for A for loop allows us to run code multiple times. We can use this to run a function multiple
times.

20 Alan Richardson
Hacking JavaScript EvilTester.com

for(var x=1;x < 100; x++){


console.log(" hello " + x);
}

The above will print:

hello 1
hello 2
...
hello 99

The ... represents the other 96 lines of output .e.g. hello 3, hello 4, etc.

With the for loop we basically said:

• start x at 1
• while x is less than 100
• write “hello” and the value of x to the console
• increment x (x++ means add 1 to x)

When you type the for loop into the console, you need to enter all the lines at the same time otherwise
you’ll see a syntax error:

> for(var=1;x<100;x++){
x Uncaught SyntaxError: Unexpected token =

You’ll either want to write your code all on one line

for(var x=1;x < 100; x++){console.log(" hello " + x);}

Or, write it in a text editor and then paste it into the console.

I could run the randomNumberUpTo function several times and make sure the output was correct.

for(var x=1;x < 100; x++){


console.log(randomNumberUpTo(3));
}

After running the above, it should call randomNumberUpTo 99 times and I should only see the num-
bers 0,1,2 in the console, giving me more confidence that the randomNumberUpTo function works as
expected.

Note:

• You might see numbers in icons to the left of the output e.g. (2)0 this means that 0 appeared

Alan Richardson 21
EvilTester.com Hacking JavaScript

in the console log twice in sequence but was only displayed once.
• This helps cut down on ‘noise’ if a JavaScript error is constantly being written to the console

Arrays

The sentences object is an ‘array’.

See w3schools.com/js/js_arrays.asp

We can interact with the array.

• sentences[0] would return the first item in the array


• sentences.length would return the length of the array
• sentences[sentences.length-1] would return the last value in the array

If we wanted, we could manipulate the array and change it

• sentences[0] = "bob" would change the first sentence in the array to ‘bob’

Note:

If you do change anything in the objects you can always refresh the web page to return them to
normal.

Objects

Objects in JavaScript are a bit like arrays, but instead of number indexes, they are “name:value”
properties and you can use the name as an index.

• phrases["start"] would return the “start” array


• phrases.start would return the “start” array

See w3schools.com/js/js_objects.asp

Interacting with the sloganizer

We now have enough JavaScript knowledge to do a lot of interaction with the sloganizer.

Look at the code for random_sentence:

function random_sentence(){
var sentence = getSentence();
return process_sentence(sentence);
}

22 Alan Richardson
Hacking JavaScript EvilTester.com

This basically returns a random sentence template and calls process_sentence to generate a random
version of that template.

The var creates a ‘variable’ called sentence which stores the string value returned by getSentence
.

We could do this via the console.

Instead of calling getSentence to generate a random sentence, we could choose one of the sentences
from the array and call process_sentence directly:

• process_sentence(sentences[0])

This would allow us to test the first sentence template and make sure it worked.

By calling JavaScript functions directly we can interact with the JavaScript application at whatever
functions the application exposes.

Exercise:

• use a for loop to generate 100 variations of sentence[0] by calling process_sentence


• amend the value of sentence[0] to be bob and try your for loop again
• call the removeSpacesAtStart method with a string
• call the removeSpacesBeforePunctuation method with different string values and check
that it works as you expect
• generate 1000 sentences with random_sentence

Advanced Techniques

setInterval

There is another more advanced way of creating loops with our JavaScript code.

And this moves us into the realm of ‘autonomous’ bots.

Instead of a loop, I’m going to create a ‘thread’ where a function is run at a time interval I decide.

Using the setInterval command.

With the Evil Tester Sloganizer

• The Evil Tester Sloganizer v 1

I could generate a new slogan every second:

var sloganbot = setInterval(function(){changeSlogan()},1000)

Alan Richardson 23
EvilTester.com Hacking JavaScript

This basically says, create a ‘thread’ which runs every 1000 milliseconds, and it runs the function which
executes the code changeSlogan().

The code in the function(){...} can be as complicated as you like and can use any function or
object accessible in the global scope.

We don’t have to assign it to a variable i.e. var sloganbot =

But, by assigning it to a variable it gives me the ability to stop the bot or ‘thread’ from running.

If I issue the following command at the console:

clearInterval(sloganbot)

Then the slogan will stop changing every 1000 seconds.

You could use this to:

• simulate more ‘user oriented’ type actions e.g. create a todo every 3 seconds.
• ‘do things’ while you use the application, e.g. create todos in the background while you use the
GUI

Also you can have multiple functions controlled by setInterval so I could also have.

var fixedbot = setInterval(function(){document.getElementById("slogan").


innerHTML="Hello World"},5000)

And every 5 seconds fixedbot will set the slogan to "Hello World"

This is incredibly flexible I just recommend that you assign the return value from setInterval to a
variable so that you can stop it, when you want to with clearInterval.

Hack the Sloganizer to create your own slogans

Using the existing structures:

• sentences[8] is a simple template "#o_just #just_because"

The values in the String are keys into the phrases map.

We could override the existing data in the phrases with our own phrases by entering the following code
into the console.

phrases['o_just']=["Since when did I", "But you always", "He will rudely"
];
phrases['just_because'] = ["kick a football", "smoke bananas", "sing on
the phone"];

24 Alan Richardson
Hacking JavaScript EvilTester.com

The Sloganizer takes each value in the template, and expands it. If it finds multiple phrases associated
with each key then it randomly picks one.

Running the code that follows would create 100 slogans in the console based on the above phrases.

for(x=0;x<100;x++){
console.log(process_sentence(sentences[8]));
}

e.g.

But you always kick a football


He will rudely kick a football
But you always smoke bananas
Since when did I sing on the phone
But you always sing on the phone

Try this for yourself with your own phrases Strings.

Using New Structures

Sentences is an ‘number indexed’ array so we push to it.

Phrases is a ‘key indexed’ array so we can create a new key.

Here is a design for sentence generation.

Identify a basic sentence:

• “I like eating mice”

Create a template for it, splitting into phrases:

• sentence: “#i_do_like #i_do_like_doing #i_like_doing_with”

Create multiple instances of the phrases:

• i_do_like: “I like”, “I hate”, “I despise”, “I loathe”, “I love”


• i_do_like_doing: “eating”, “smashing”, “feeding”, “teasing”, “tickling”, “destroying”, “making”,
“teaching”
• i_like_doing_with: “cats”, “dogs”, “mice”, “peers”, “Systems”, “Managers”, “Testers”, “Developers”,
“code”, “beliefs”, “memories”, “attitudes”

We can add this design to the sloganizer by running the code below (Implementation):

sentences.push(
"#i_do_like #i_do_like_doing #i_like_doing_with");
phrases['i_do_like']=

Alan Richardson 25
EvilTester.com Hacking JavaScript

["I like", "I hate", "I despise", "I loathe", "I love"];
phrases['i_do_like_doing']=
["eating", "smashing", "feeding", "teasing",
"tickling", "destroying", "making", "teaching"];
phrases['i_like_doing_with']=
["cats", "dogs", "mice", "peers", "Systems",
"Managers", "Testers", "Developers", "code",
"beliefs", "memories", "attitudes"];

Since the sentence will be added to the end of the sentences array I can use the last sentence:

sentences.length-1

The code below generates 100 phrases using the template we just added.

for(x=0;x<100;x++){
console.log(process_sentence(sentences[sentences.length-1]));
}

Try to design and implement your own phrases.

Practical application

The Sloganizer may seem like a frivolous toy. And it is.

But it also represents a very simple approach to test data generation.

If you want to research more about this then search for “Generative Grammar”.

And you may find additional academic on the application to software testing by searching for “Genera-
tive Grammar test data software testing”.

Some Exercise Answers

Generate a random sentence using a sentences template

process_sentence(sentences[0]);

Can you see the difference between these approaches?

console.log(process_sentence(sentences[0]));

26 Alan Richardson
Hacking JavaScript EvilTester.com

Generate 100 random sentences from a specific template

for(x=0;x<100;x++){
console.log(process_sentence(sentences[0]));
}

Generate 1000 random sentences

for(x=0;x<1000;x++){
console.log(random_sentence());
}

Alan Richardson 27
EvilTester.com Hacking JavaScript

Case Study - A Link Checker In The JavaScript Console

TLDR; A simple link checker running from a snippet or console has some secondary advantages like
jumping to the links and showing CSP and CORB errors

To experiment with more with JavaScript and working more from the console, I wanted to write more
code and try and write simple tooling from the console. This section explains the basics of a simple
Link Checker.

External Link Checkers

I use link checkers like:

• Total Validator

To externally crawl my site for errors.

External crawlers are important for finding the status of pages e.g. 404, 200

Building a Link Checker

As a quick experiment I wanted to see how much of a link checker I could build in JavaScript and run it
from snippets.

I have uploaded all the code as a Gist:

• https://gist.github.com/eviltester/8a27ca23f7475d6b47fc99fc11ad3198

Find all the links

In essence, what I do is:

• find all the links


• iterate over them

Which looks like this:

var links = document.querySelectorAll("a");


var linkReport = [];
links.forEach(function(link){
var reportLine = {url: link.getAttribute('href'), status:0, message :
"", element : link};
linkReport.push(reportLine);

28 Alan Richardson
Hacking JavaScript EvilTester.com

// do stuff to the reportLine and link here


});
console.table(linkReport);

You could run this from the console, or add it as a snippet.

When it finishes it uses the console.table functionality to output all the objects.

The objects are created in the line:

var reportLine = {url: link.getAttribute('href'), status:0, message : "",


element : link};

In this form it doesn’t really do anything, but. . .

...if anything caught your eye in the table, say it was link 70 in the table, then you could, in the
console...

Scroll it into view:

linkReport[70].element.scrollIntoView()

And highlight it on screen with:

linkReport[70].element.style.backgroundColor = "red"

So it might be useful in that simple form.

Checking Links

I wanted to check the links by making a HEAD request.

I knew this wouldn’t work for all links because the browser would block some of the requests due to
cross site scripting concerns.

Extensions like Check My Links will use Chrome APIs to avoid the XSS issues.

But I carried on regardless to see if anything interesting would happen.

I initially used XMLHttpRequests:

var http = new XMLHttpRequest();


http.open('HEAD', reportLine.url);

http.onreadystatechange = (function(line,xhttp) {
return function(){
if (xhttp.readyState == xhttp.DONE) {
line.status = xhttp.status;
line.message = xhttp.responseText + xhttp.statusText;

Alan Richardson 29
EvilTester.com Hacking JavaScript

linksChecked++;
console.table(xhttp);
}
}
})(reportLine, http);
http.send();

This console logs the http request as it works.

Because this is callback based, if I output the table after the loop it would not have all the request
status so I maintain a count of links checked linksChecked++; and added a polling mechanism after
the loop:

var finishReport = setInterval(


function(){
if(linksChecked>=linkReport.length){
console.table(linkReport);
clearInterval(finishReport);
}
}
, 3000);

This way the final console.table report is only shown when the number of links check matches the
number of links in the array.

Simple link checker using XMLHttpRequest

Giving me a simple link checker like this:

var links = document.querySelectorAll("a");


var linkReport = [];
var linksChecked=0;
links.forEach(function(link){
var http = new XMLHttpRequest();
var reportLine = {url: link.getAttribute('href'), status:0, message :
"", element : link};

http.open('HEAD', reportLine.url);
linkReport.push(reportLine);

http.onreadystatechange = (function(line,xhttp) {
return function(){
if (xhttp.readyState == xhttp.DONE) {
line.status = xhttp.status;
linksChecked++;
line.message = xhttp.responseText + xhttp.statusText;
console.table(xhttp);
}

30 Alan Richardson
Hacking JavaScript EvilTester.com

}
})(reportLine, http);
http.send();
});
var finishReport = setInterval(
function(){
if(linksChecked>=linkReport.length){
console.table(linkReport);
clearInterval(finishReport);
}
}
, 3000);

Again I can scroll to link and make it visible.

One of the issues I have with Check My Links is that when a link fails it can be hard to find it on screen
sometimes. This way I can use JavaScript in the console to jump to it.

Using Fetch

I thought I’d try with Fetch and see how different the output was:

fetch(reportLine.url, {
method: 'HEAD'
})
.then(function(response) {
linksChecked++;
reportLine.status=response.status;
reportLine.message= response.statusText + " | " +
response.type + " | " +
(response.message || "") + " | " +
(response.redirected ? "redirected | " : "") +
JSON.stringify(response.headers) ;
console.table(response);
}
)
.catch(function(error){
reportLine.message = error;
console.table(error);
linksChecked++;
});

This was a little easier to use and the response had more useful information so I crudely concatenated
the response fields I was interested into the message property of the report line.

Alan Richardson 31
EvilTester.com Hacking JavaScript

Errors

When the link checker runs it shows me all the CSP errors in the console:
VM14:1 Refused to connect to 'https://help.github.com/'because it
violates the document's Content Security Policy.

And all the CORB errors:


Cross-Origin Read Blocking (CORB)blocked cross-origin response https:
//gist.githubusercontent.com/eviltester with MIME type text/plain. See
https://www.chromestatus.com/feature/5629709824032768 for more details.

This was a useful side-effect. The table report shows me a status of 0, but I can look in the console for
the other errors.

This is a useful side-effect because I don’t see these warnings with external link checkers, but it is
important to be able to check that the various XSS policies are in place, or have been deliberately eased
up on for some servers as appropriate.

I don’t think I have any other tools which provide me with this information easily.

Could I check status for these?

In order to try add even more information I thought I’d see if I could check the status for anything that
was throwing errors in the initial log.

Image tags are often used for XSS to pass information to another site, but I wanted to see if that could
give me any status information.

function imgreport(links){
links.forEach(function(link){
if(link.status==0){
// trigger error messages with status
// to the console for status of 0
var img = new Image();
img.src = link.url;
}
}
);
}

The above function creates a new image and sets the url to one of the links that failed to work with the
fetch.

32 Alan Richardson
Hacking JavaScript EvilTester.com

Would this provide more information?

It did.

With the Fetch I learned:


‘Access to fetch at ‘https://twitter.com/eviltester’ from origin ‘https://www.eviltester.com’ has
been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested
resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch
the resource with CORS disabled.

For the same URL with the image I learned:

GET https://twitter.com/eviltester 403

What else could fetch do?

I had a look at the fetch documentation and saw that it could follow the redirects for me:

fetch(reportLine.url, {
method: 'HEAD',
mode: 'cors',
redirect: 'follow'
})

So I added the url it was redirected to into the report

if(response.redirected){
reportLine.redirectedTo = response.url;
}

My final code

The final code for my linkchecker used the ‘fetch’ version as it had more actionable and useful informa-
tion.

var links = document.querySelectorAll("a");


var linkReport = [];
var linksChecked=0;
links.forEach(function(link){

var reportLine = {url: link.getAttribute('href'), status:0,


redirectedTo: "", message : "", element : link};
linkReport.push(reportLine);

console.log("HEAD " + reportLine.url);

Alan Richardson 33
EvilTester.com Hacking JavaScript

fetch(reportLine.url, {
method: 'HEAD',
mode: 'cors',
//mode: 'no-cors',
redirect: 'follow'
})
.then(function(response) {
linksChecked++;
reportLine.status=response.status;
reportLine.message= response.statusText + " | " +
response.type + " | " +
(response.message || "") + " | " +
JSON.stringify(response.headers) ;
if(response.redirected){
reportLine.redirectedTo = response.url;
}
console.table(response);
}
)
.catch(function(error){
reportLine.message = error;
console.table(error);
linksChecked++;
});

});

function imgreport(links){
links.forEach(function(link){
if(link.status==0){
// trigger error messages with status
// to the console for status of 0
var img = new Image();
img.src = link.url;
}
}
);
}

var finishReport = setInterval(


function(){if(linksChecked>=linkReport.length){
console.table(linkReport);
imgreport(linkReport);
clearInterval(finishReport);
}}
, 3000);

34 Alan Richardson
Hacking JavaScript EvilTester.com

Not an everyday link checker

I found that a useful exercise.

The link checker report is useful to me because it does reveal issues on the page that were hinted at by
icons in Chrome, but very visible in the fetch error messages.

Using the console.table allows me to sort the ‘report’ in the console to make the investigation useful,
and I learned a bit more about fetch

All the code is easy to copy and paste to experiment with from this gist

• gist.github.com/eviltester/8a27ca23f7475d6b47fc99fc11ad3198

Alan Richardson 35
EvilTester.com Hacking JavaScript

History of Game Of Life

The Game of Life is a Cellular Automata.

A Cellular Automata is a simple system where the next state of a cell in the system depends on the
environment which the cell currently finds itself in.

In the Game of Life a cell in the system is alive or dead in the next state, based on the number of
neighbours it has surrounding it.

The Game of Life is useful because it is a very visual demonstration of Cellular Automata.

You can learn more about John Horton Conway’s Game of Life here:

• https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life#Rules

• http://conwaylife.com/

This section will use the Game of Life Cellular Automata that I created to encourage JavaScript Hack-
ing.

• eviltester.github.io/TestingApp/games/ca/v1/ca.html

Programs to download, install and experiment with:

• Golly

– http://golly.sourceforge.net/
– Also available on IPad and Android

online games of life:

Cellular Automata Life Game Suitable for Playing

• https://bitstorm.org/gameoflife/

Cellular Automata Life Game Suitable for Hacking

• https://eviltester.github.io/TestingApp/games/ca/v1/ca.html

36 Alan Richardson
Hacking JavaScript EvilTester.com

Related References:

Good simple Overview

• http://www.math.com/students/wonders/life/life.html

Good set of resources

• http://www.ibiblio.org/lifepatterns/

– http://www.ibiblio.org/lifepatterns/october1970.html

Wolfram description

• http://mathworld.wolfram.com/GameofLife.html

History of Computer Game Design - Stanford

• http://web.stanford.edu/class/sts145/
• http://web.stanford.edu/class/sts145/html/library.htm

Recommended Books

• Artificial Life - by Stephen Levy


• The Garden in the Machine by Clause Emmeche
• A New King of Science by Stephen Wolfram available online free

Investigate the Invasion

This game of life differs from other Games of life in that this one never ends.

• eviltester.github.io/TestingApp/games/ca/v1/ca.html

Normally the Game of Life is a closed system:

• It starts with a pre-populated world


• It iterates over a series of rules
• New life is only generated based on those rules
• The world either reaches a stable point with oscillators or it dies

This world is different.

This world is an Open System and has an ongoing invasion. Where a new lifeform is randomly added
every 100 milliseconds.

Alan Richardson 37
EvilTester.com Hacking JavaScript

An Invasion Challenge

One of the challenges suggested in the game is to have an invasion of gliders.

We can use the existing startInvasion function to help us figure out what to do. It basically picks a
random function from addLifeForms which adds a new lifeform to the world population.

We can do that.

First control the invasion

But first we have to learn how to control the invasion.

Fortunately that’s easy because someone has written the code to do that.

We can stop the invasion by calling:

stopInvasion();

We can start an invasion with:

startInvasion(100);

Where 100 is the amount of milliseconds before the next lifeform is added.

Create a Glider

One of the functions in addLifeForm is glider so I can use that to create a glider, and there are
examples of how to use that in the source code:

addLifeForms.glider(world,10,0);

Which creates a glider at position (10,0)

I could create an invasion of gliders like that

var gliderInvasion = setInterval(function() {


addLifeForms.glider(world, 10, 0);
}, 100);

But they are created so fast they collide into each other.

So I’ll make it one every second:

var gliderInvasion = setInterval(function() {


addLifeForms.glider(world, 10, 0);
}, 1000);

38 Alan Richardson
Hacking JavaScript EvilTester.com

But an invasion should be random

Really we should have the gliders appear in a random position.

And we can use the code in the existing invasion to do that:

First stop the old invasion:

clearInterval(gliderInvasion)

Then start our new invasion:

var gliderInvasion = setInterval(function() {


addLifeForms.glider(world, getRandomInt(0, world.xSize - 50),
getRandomInt(0, world.ySize - 50));
}, 1000);

And that’s better but we probably want it faster than that.

So amend the interval time.

var gliderInvasion = setInterval(function() {


addLifeForms.glider(world, getRandomInt(0, world.xSize - 50),
getRandomInt(0, world.ySize - 50));
}, 100);

And you can change it to whatever you want.

var gliderInvasion = setInterval(function() {


addLifeForms.glider(world, getRandomInt(0, world.xSize - 50),
getRandomInt(0, world.ySize - 50));
}, 1);

The easiest way to see the effect at the moment is to:

• refresh page
• quickly stopInvasion()

Then start your new invasion.

And that’s how we create an invasion of gliders.

Watch The Video

https://youtu.be/CeOzcn7pBQY

Alan Richardson 39
EvilTester.com Hacking JavaScript

Change Colour of Cellular Entity

The simplest thing we can do to this game of life is to change the colour.

It is also the most visible thing.

Using the game:

https://eviltester.github.io/TestingApp/games/ca/v1/ca.html

Colour in the Game

In the code we have the World function - which is an object class.

And the World object has an entityColour.

If we can change that, then we can change the colour.

I could use any six values from 0-9, A-F to make an HTML colour code

e.g. http://htmlcolorcodes.com

Change colour by debugging

I can change it by debugging.

I set a break point on the line where the colour is set in the sources view.

• Line 153
• this.entityColour = "#FF0000";

Refresh the page.

Step over that line so the colour is set.

Then in the console - if I press esc to get the console up.

I can change the colour in the console:

this.entityColour = "#111111";

Change colour from console when runnning game

An other easy way to change the colour is to use the console.

40 Alan Richardson
Hacking JavaScript EvilTester.com

If I inspect element and find where World is instantiated with new. i.e. ctrl+F and search for new
World.

I can see it is in a variable called world with a lower case w.

var world = new World(worldSizes.myWorldWidth,


worldSizes.myWorldHeight);

And I can change that whenever I want:

world.entityColour = "#111111";

Watch The Video For Colour Change

https://youtu.be/gWnvKQOb2yc

Change Colour Automatically

One of the suggested challenges listed in the source for the Cellular Automata game is to cycle through
the colours randomly.

We already know how to set the colour.

world.entityColour = "#111111";

So all I have to do is have a bot to change colour every set time interval - say 1000 milliseconds.

The challenge is that I need to use a hex value to do that. So let’s figure that out first.

Random Hex Value

In JavaScript:

• I can use 0xFF as a Hex integer value, and it is 255


• I can use the toString method on a Number to convert a number to a base e.g. base 2 for binary
or base 16 for hex:

var myNum=255;
myNum.toString(2);
myNum.toString(16);

• I need to get a 6 character string, even if my hex value is only FF and I can do that by creating a
string and using the last 6 characters e.g.

Alan Richardson 41
EvilTester.com Hacking JavaScript

"EvilTester".substr(-6)

• And I want my string to be "0" padded at the front so I’ll just add "000000" at the front of any
string:

("000000" + "FF").substr(-6)

• And I want a Hash # in front

"#" + (("000000" + "FF").substr(-6))

If I put all that together I can get a hex code for any number variable:

var myNum=3;
"#" + (("000000" + myNum.toString(16)).substr(-6))

I really want a random number - and if I look in the code for the game I can see it already has a random
number generator, so I’ll use that.

getRandomInt(0, 0xFFFFFF);

And add that in

"#" + (("000000" + getRandomInt(0, 0xFFFFFF).toString(16)).substr(-6))

And I have a way to generate a random HTML hex colour value.

Randomly set the colour every second

I’ll create a bot to use what we’ve just experimented with to change the colour every 1000 millisec-
onds.

I’ll edit and run this from the Snippets tab in Sources

var colourChangeBot = setInterval(function() {


world.entityColour = "#" + (("000000" + getRandomInt(0, 0xFFFFFF).
toString(16)).substr(-6));
}, 1000);

And I can stop the bot with:

clearInterval(colourChangeBot);

42 Alan Richardson
Hacking JavaScript EvilTester.com

Make Bot Faster or Slower

And if I change the value 1000, then I can make it faster, or slower:

• 500 - every half second


• 200 - every 200 milliseconds

Danger Flashing Lights.


Just be careful you don’t make it so fast that you have a seizure.

Cycle over all the colours

This is a bit slower, but a bit more sedate, you might want to put some classical music on for this.

var currColour = 0;
var colourChangeBot = setInterval(function() {
world.entityColour = "#" + ("000000" + currColour.toString(16)).substr
(-6);
currColour++;
if (currColour >= 0xFFFFFF) {
currColour = 0;
}
}, 1)

Watch The Video for Automatic Colour Change

https://youtu.be/hfE99d4Slck

References

• http://www.w3schools.com/jsref/jsref_tostring_number.asp
• http://www.w3schools.com/jsref/jsref_substr.asp
• Chambers Brothers - Time has come today - “My Soul has been psychedelicized”
• https://www.youtube.com/watch?v=AQSjV4DZ-Gg

Change World Size

One of the challenges in the Cellular Automata game is changing the world size.
https://eviltester.github.io/TestingApp/games/ca/v1/ca.html

Alan Richardson 43
EvilTester.com Hacking JavaScript

Scouting for Clues

There is a clue in the game code, because we know that it does some resizing when we change the
window size.

And if we look in that section of the code for hints we can see:

worldSizes.calculateScales();

And lower in the code we can see that worldSizes is used to create the world.

var world = new World(worldSizes.myWorldWidth, worldSizes.myWorldHeight);

Let’s Change the World

Make is smaller

worldSizes.myWorldWidth=100;
worldSizes.myWorldHeight=100;
worldSizes.calculateScales();

Make it bigger

worldSizes.myWorldWidth=1000;
worldSizes.myWorldHeight=1000;
worldSizes.calculateScales();

Make it smaller worked, but make it bigger didn’t really work.

I think I also need to tell the world that it is bigger

worldSizes.myWorldWidth=1000;
worldSizes.myWorldHeight=1000;
world.xSize=1000; world.ySize=1000;
worldSizes.calculateScales();

That worked - and its a little slower now, because thats 1000 x 1000 grid, which is 1,000,000 (1 million)
cells!

I hope you have enough memory in your machine if you try this.

An easier way to experiment is to only have the literal 1000 on one line and use the worldSizes to
change the world.

worldSizes.myWorldWidth=200; worldSizes.myWorldHeight=200;
world.xSize=worldSizes.myWorldWidth; world.ySize=worldSizes.myWorldHeight;
worldSizes.calculateScales();

44 Alan Richardson
Hacking JavaScript EvilTester.com

The ZX-81 had a resolution of 64x48, and it was black and white, so let’s simulate that.

worldSizes.myWorldWidth=64; worldSizes.myWorldHeight=48;
world.xSize=worldSizes.myWorldWidth; world.ySize=worldSizes.myWorldHeight;
world.entityColour="#000000";
worldSizes.calculateScales();

That’s probably a bit faster than a ZX-81 could calculate though.

Change the Speed

stopInvasion();
stopGame();
startGame(1000);
startInvasion(3000);

That’s probably more realistically what a ZX-81 could do (if I was programming it)
And now we can change the size of the world and control the game.

Watch The Video

https://youtu.be/lLnyNP33S_Q

Create a Random World

To create a random cellular world:


https://eviltester.github.io/TestingApp/games/ca/v1/ca.html
We first want total control over the game.
We can see in the code how to:

• start game

– startGame(5)

• stop game

– stopGame()

• stop invasion

– stopInvasion()

And we’ll need to know that if we want to take control:

Alan Richardson 45
EvilTester.com Hacking JavaScript

Stop and Clear the Game

First stop everything:

stopGame();
stopInvasion();

It would be useful to also clear the display.

Inside World I can see nukeEmAll so that might help:

world.nukeEmAll();

That did work, but we’ll only see the results if we start the game again:

startGame(5);

And then stop it:

stopGame();

Now we can randomly generate stuff.

Randomly generate stuff

I can randomly add a cell:

world.addToPopulation(new LifeForm().move(0, getRandomInt(0, world.xSize),


getRandomInt(0, world.ySize)));

You can’t see it because the game isn’t running, but if I have a look at:

world.population

Then I’d see 1 item.

So I’ll add items in a loop, and create 100 of them:

for(var itemLoop=0; itemLoop < 100; itemLoop++){


world.addToPopulation(new LifeForm().move(0,
getRandomInt(0, world.xSize),
getRandomInt(0, world.ySize)));
}

If I want to reset the population to make it easier to see then I could do that:

world.population = [];

46 Alan Richardson
Hacking JavaScript EvilTester.com

That seems to work better than nuke em all

Now If I start the game, we should see the results:

startGame(5);

100 might not actually be big enough, depending on the size of the world, to create more for a viable
population for survival.

But we can easily run the loop again by pressing ‘up’;

And can change the number of times around the loop:

for(var itemLoop=0; itemLoop < 1000; itemLoop++){


world.addToPopulation(new LifeForm().move(0, getRandomInt(0, world.
xSize), getRandomInt(0, world.ySize)));
}

And the easiest way to clean the board when the game is running is to clear the population:

world.population = [];

Experiment and Watch the Video

Experiment with different loop sizes to see what works for your world - remember its a harsh world out
there for these cells so sometimes you need to start with a lot of them.

https://youtu.be/uZv2s5QjPps

Alan Richardson 47
EvilTester.com Hacking JavaScript

Other Ways To Use These Skills

Bookmarklets

There is a lot to cover and research for bookmarklets.

But the basics are:

• a ‘javascript:’ link stored as a bookmark in your browser


• when you click the bookmark it executes code on the current page rather than taking you to a
new page

The way it works is that we:

• have some JavaScript code that works


• wrap the code in an anonymous function that runs immediately
• prefix with “javascript:” and store as a bookmark

e.g.

• Some code that runs on the current page

document.title=window.prompt("","hello");

• As an anonymous function that executes immediately:

(function(){document.title=window.prompt("","hello");})()

• Prefixed with “javascript:”

javascript:(function(){document.title=window.prompt("","hello");})()

I could paste the above into a bookmark manager and then execute.

Starting

When I first started messing about with bookmarklets I used the following code to create them.

"javascript:(function(){" + encodeURI(window.prompt("")) + "})()"

I would type the above into the console, or run from a snippet, paste my JavaScript code into the
prompt then copy and paste from the console into the bookmark manager.

I eventually added a little more code and created a small app.

48 Alan Richardson
Hacking JavaScript EvilTester.com

• https://github.com/eviltester/bookmarklet
• https://eviltester.github.io/TestingApp/apps/bookmarklet/version/1/bookmarklets.html

Resources:

• https://adrianroselli.com/2015/01/css-bookmarklets-for-testing-and-fixing.html
• http://www.squarefree.com/userstyles/make-bookmarklet.html
• https://lisacrispin.com/2016/07/24/step-comfort-zone/
• https://www.smashingmagazine.com/2010/05/make-your-own-bookmarklets-with-jquery/

Tools to create bookmarklets

• https://eviltester.github.io/TestingApp/apps/bookmarklet/version/1/bookmarklets.html
• https://ted.mielczarek.org/code/mozilla/bookmarklet.html
• http://www.brainjar.com/js/crunch/demo.html

Writing Chrome Extensions

It is possible to use the knowledge of JavaScript you have gained to write Chrome Extensions, and it
might be worth learning more about Extensions to practice in the future.

I created a tutorial showing how to create a Chrome extension on YouTube

• https://www.youtube.com/watch?v=Olz4wo-ILwI

And I have a couple of examples of extensions on github

• one that I’m building with Viv Richards https://github.com/eviltester/usefuljssnippetextension


• one that I use for my own adhoc experiments https://github.com/eviltester/javascriptbotshowcase

Working with Chrome extensions gives you access to a few more APIs to avoid some of the constraints
of cross site scripting.

I have a series of blog posts with videos showing how t create a Chrome Extension:

• eviltester.com/categories/chrome-extension

The tutorial posts above show how to create a Chrome Extension which generates CounterStrings, and
goes through the full process of creating a prototype, building an extension, and releasing it to the
Chrome Store.

Alan Richardson 49
EvilTester.com Hacking JavaScript

Also

Do some additional research to follow up on these topics.

I’ve found all of these to be useful ways to learn more, and improve my JavaScript.

• JavaScript Injection in Selenium


• JavaScript Injection for Security Testing
• Tool Extensions - Fiddler, OWasp ZAP Proxy - what else can we script in JavaScript?
• Create Your Own Games

– you’ve seen the basic structure


– libraries to use, etc.

50 Alan Richardson
Hacking JavaScript EvilTester.com

Appendices

The sections that follow contain, primarily reference information and links.

Alan Richardson 51
EvilTester.com Hacking JavaScript

Practice Apps To Test

I have written a lot of applications which you can use to practice your JavaScript Hacking skills.

Testing Apps

https://eviltester.github.io/TestingApp/

This page has links to:

• a bunch of buggy games

– Console Driver
– Canvas Driver
– The Coloured Square Game
– Number Hover Text Game
– The Coloured Square Changing Game
– The Random Walker Game
– The Grid Walker Game
– The Protect The Square Game

• simple apps

– 7 CharVal
– CounterString Generator
– Bookmarklet Generator
– e-Primer
– iframe Search
– Responsive Test Tool
– Sloganizer

Todo App

This is a simple todo list application created to support my LinkedIn Training course WebDriver Page
Objects and Abstractions.

• Todo App
• https://www.eviltester.com/page/tools/thetodoapp/

See what you can do with it. I recommend trying to automate the creation of test data from the
JavaScript Console.

52 Alan Richardson
Hacking JavaScript EvilTester.com

Tips for Learning JavaScript

TLDR; A lot of good resources for learning JavaScript exist. And you do not need to install an IDE, you can
learn JavaScript in the console.

How does learning JavaScript help?

• When testing a web app you can look at the code


• Understand the code
• Understand errors written to the Dev Tools Console
• Workaround application defects
• Automate in the browser

– I can nudge the client side into different states by executing ad-hoc JavaScript through the
console

• The DOM web developer displays make ever more sense


• Create helper tools as BookMarklets
• Improve your use of WebDriver’s JavascriptExecutor
• In strange and mysterious ways that will surprise you once you learn JavaScript.

Learning JavaScript increases the Surface Area of the System that we can pull information from
(i.e. model it), and potentially observe, interrogate and manipulate in more dimensions.

It increases our options, and therefore our ability to handle an increased variety of applications and
technologies.

It also helps my automation;

• My ability to use the JavaScript calls has improved so I don’t have as much trouble with web
sites that don’t play nice
• My CSS selector skills have improved

Clearly for most Selenium automation purposes, we don’t need a large grasp of JavaScript, we mainly
do quick DOM access scripts, the kind of thing you would do through the console for debugging.

Alan Richardson 53
EvilTester.com Hacking JavaScript

Any Resources? If you are a tester and want to learn JavaScript...

Tip 1... Automating in the Browser

My Test Automation U Course

https://testautomationu.applitools.com/automating-in-the-browser-using-javascript/

• a free course
• explains how to use the browser dev tools for automating

Tip 2... Eloquent JavaScript

Read (free) Eloquent JavaScript

• https://eloquentjavascript.net/
• Code Sandbox - https://eloquentjavascript.net/code/

Good for understanding the language. And Code Sandbox good for seeing code running.

Pull the language together to help you understand it as a programmer.

Tip 3... JavaScript Enlightenment

Read (free) JavaScript Enlightenment

• https://frontendmasters.com/books/javascript-enlightenment/

An indepth look at ‘modern’ JavaScript features.

Tip 4... Speaking JavaScript

Read (free) Speaking JavaScript

• http://speakingjs.com/

54 Alan Richardson
Hacking JavaScript EvilTester.com

A good overview of the syntax and language.

Tip 5... DOM Elightenment

Read (free) DOM Elightenment

• http://domenlightenment.com/

Understand and manipulate the DOM in depth. We will do this a lot when automating from the
browser.

Tip 6... JavaScript Design Patterns

Read (free) JavaScript Design Patterns

• https://addyosmani.com/resources/essentialjsdesignpatterns/book/

Much of the use of JavaScript will be tactical unless being used as the main language for coding
automating or writing apps. This is important to learn when you start writing more code, especially if
you have to maintain it. And can be useful for helping understand structure of other peoples code.

Tip 7... Support Page

The support page for my Test Automation U Course (has even more links):

• https://www.eviltester.com/page/onlinetraining/testautomationujs/

Tip 8... Go Make Things

Subscribe to Chris Ferdinandi’s “Go Make Things” JavaScript newsletter.


Short, regular posts with easy to read and understand JavaScript code snippets.

• https://gomakethings.com/articles

Alan Richardson 55
EvilTester.com Hacking JavaScript

Tip 9... Useful Snippets

Check out the Chrome Extension “Useful Snippets”

• https://github.com/eviltester/usefuljssnippetextension

Viv Richards @11vlr and I wrote this web testing tool.

And the benefit is, each time you run a command you see the JS in the console.

Tip 10... JavaScript for Cats

Have a look at “JavaScript for Cats”. A tutorial web page, where all the examples and coding take place
in the dev tools. And it has some additional resources for future reading.

• http://jsforcats.com/

A fast overview you can use in the browser.

Tip 11... Javascript Weekly

Subscribe to the JavaScriptWeekly.com email newsletter.

Or subscribe to their RSS feed, or read the backlog of newsletters.

This provides a good summary of posts around the web related to JavaScript.

Tip 12... Order to use them

1. Subscribe to “Go Make Things” and be drip fed information - gomakethings.com


2. Subscripe to “JavaScriptWeekly.com” and receive a weekly prompt to continue to learn.
3. Read JavaScript for Cats jsforcats.com
4. Follow My Test Automation U Course Automating in the browser
5. Read Speaking JavaScript speakingjs.com
6. Eloquent JavaScript eloquentjavascript.net
7. Read DOM Elightenment domenlightenment.com
8. JavaScript Design Patterns addyosmani.com/resources/essentialjsdesignpatterns/book/

56 Alan Richardson
Hacking JavaScript EvilTester.com

9. Course Support Page - eviltester.com/page/onlinetraining/testautomationujs


10. Useful Snippets - github.com/eviltester/usefuljssnippetextension
11. Read JavaScript Enlightenment frontendmasters.com/books/javascript-enlightenment

Free Video Inside

youtu.be/TBQIrqTyT3I

Alan Richardson 57
EvilTester.com Hacking JavaScript

Just Enough JavaScript To Be Dangerous Reference

This section will provide a short reference to JavaScript. Not all of JavaScript you understand, just
enough to be dangerous!

All of the code here has been used in the various hacks and testing code samples. So I cover, just
enough to help you understand and implement the various hacks needed.

Console

Right click on your web page to access the developer tools.

Click on the ‘Console’ tab and you can start writing JavaScript.

Variables

Create variables using the var keyword.

var debugMode=true;

• The variable has a ‘name’ i.e. debugMode


• we could ‘declare’ it by missing out the =true
• we are initializing it (setting its value for the first time) with =true
• Add the ‘;’ at the end of the line
• The variable has a value i.e. true
• we can type the variable name into the console to see information about it
• we assign it a new value with = e.g. =false

Variables can hold pretty much any type of information e.g.

• boolean : true, false


• String : "Bob"
• Integer : ‘23’

Operators

-+/*

• ++ to increment a variable

• -- to decrement a variable

58 Alan Richardson
Hacking JavaScript EvilTester.com

• += to add a value e.g. x+=5 (also /=,*=,-=)

• ‘+’ can be used to add numbers and concatenate strings

Strings

Strings can be "" or ''

• substr(...) - get sub string

– .substr(-2) - the last 2 characters


– .substr(2) - the string starting from the 2nd character
– .substr(2,8) - the string from chars 2 to 8

• split(...) - create an array by splitting based on a char

– .split(",")

• parseInt("10") - takes a string and returns an integer, whitespace is ignored, NaN returned if
not a convertable String

– developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/parseInt

• .length - length of string


• .concat(...) - return string with argument ... concatenated

Integers

Hex

• myNum.toString(16) - convert to hex


• var myNum = 0xFFFFFF; - initialize a variable using HEX notation

Math library/Object

JavaScript has a standard Math library/Object to do math stuff

• Math.random()

w3schools.com/js/js_math.asp

Alan Richardson 59
EvilTester.com Hacking JavaScript

Using the Console object

If I type debugMode into the console I will see the value.

But I an also print information to the console with console.log

e.g.

• console.log('Hello');
• console.log(debugMode);

Alerts and Prompts

We can make pop up dialogs appear.

alert("Hello");

prompt("type your name",'no name');

• The second argument is optional


• prompt returns what the user types in

But this stops other JavaScript from running until the alert has been dismissed.

Note "" and '' are pretty much interchangeable.

Functions

Functions let us create code that we can call at any time we want.

function randomNumberUpTo(theVal){
return Math.floor(Math.random() * theVal)
}
randomNumberUpTo(10);

• This is a function
• called randomNumberUpTo
• it takes a single argument theVal‘
• it uses the JavaScript Match library
• it returns a random number up to the value of theVal

We can allocate functions to variables.

60 Alan Richardson
Hacking JavaScript EvilTester.com

var randomNum = function randomNumberUpTo(theVal){


return Math.floor(Math.random() * theVal)
};
randomNum(10);

Iteration

for Loops

for(x=0;x<100;x++){
console.log("line " + x);
}

• loop from 0 to 99 (x<100)


• increment by 1 each time (x++)
• each time run the code within {}

– log to the console "line " with x appended e.g. ‘line 0’, ‘line 1’

Arrays

Position Index

var colours = ["red", "green", "blue", "grey", "black"];

• An array that is indexed by position

– colours[0]==="red" arrays start at index 0


– colours[5]===undefined because the last index in the array is 4

• Arrays have length

– colours.length===5

• The last index in an array is length-1

– colours[colours.length-1]==="black"

• We can set the values in the array

– colours[0] = "white"; the first item in the array is now "white"

• .join(",") - create a string by concatinating all elements together with ","

Alan Richardson 61
EvilTester.com Hacking JavaScript

Key Indexed

Arrays can be ‘key’ indexed;

var colours = [];


colours["stop"]="red";

Then colours["stop"]==="red" is true.

Arrays and Objects are very similar

var colours = {"stop":"red"};

Then colours["stop"]==="red" is also true.

• Objects {}
• Arrays []

Selection and Conditions

if statements

var debugMode=true;
if(debugMode===true){
console.log("debug mode is on");
}else{
console.log("debug mode is not on");
}

JavaScript has strange equality operators:

• === check if something equals

Run Code Every X milliseconds

setInterval runs a function every ‘X’ milliseconds

var sloganbot = setInterval(changeSlogan,1000)

• every 1000 milliseconds run the function changeSlogan

var sloganbot = setInterval(function(){changeSlogan()},1000)

• every 1000 milliseconds run the ‘anonymous’ function

62 Alan Richardson
Hacking JavaScript EvilTester.com

– in this case the ‘anonymous’ function calls the changeSlogan function

• You can add as much code as you want in an ‘anonymous’ function

Stop an ‘interval’ with ‘clearInterval’

clearInterval(sloganbot)

Interact with the DOM

Finding Elements

• getElementById
• getElementsByClassName
• getElementsByName
• getElementsByTagName
• querySelector

– use CSS selector as the query argument to match first element

• querySelectorAll

– return all in an array using CSS selector

can find from an element or document

Change Style Element Attributes

document.getElementById("theSquare").style.backgroundColor = "red";

• get individual elements with getElementById


• access the style attribute of an element with .style

Hiding an element:

document.getElementById("theSquare").style.display="none"

• set to “block” or "" to display it

Change Element Attributes

Alan Richardson 63
EvilTester.com Hacking JavaScript

document.getElementsByClassName("title")[0].
setAttribute("style","display:none");

document.getElementsByClassName("title")[0].
getAttribute("style");

Change Element Text

elem.innerHTML = "Hello";

Changing Event Code

The system might have defined events.

<div class="title">
<button class="title" onclick="changeSlogan()">I Want A Slogan</button
>
</div>

We can change them.

onclick="changeSlogan()"

var theButton=document.getElementsByClassName("title")[2];
theButton.onclick = function() {
alert('hello');
};

var theButton=document.getElementsByClassName("title")[2];
theButton.onclick = null;
theButton.addEventListener("click", function(){
alert('from adding event');
}, false);

• false is for ‘useCapture’ - true for capturing phase, false (default) for bubbling phase

– bubbling for handling child events


– capturing - has to be element clicked on

• ‘useCapture’ is optional

Create function into a variable if we want to remove the event Listener

var theButton=document.getElementsByClassName("title")[2];
theButton.onclick = null;

64 Alan Richardson
Hacking JavaScript EvilTester.com

var eventHandlingFunction = function(){alert('from adding event');}


theButton.addEventListener("click", eventHandlingFunction, false);

Same phrase must be specified to remove it.

theButton.removeEventListener("click", eventHandlingFunction, false);

• The onclick attribute will operate alongside even handlers.

Good JavaScript References For Future Study

Tutorials

• w3schools.com/js
• Mozilla Developer Network Javascript
• htmldog.com/guides/javascript
• learn-js.org

References

• w3schools.com/jsref

Alan Richardson 65
EvilTester.com Hacking JavaScript

JavaScript Hacking Tips

General Tips

• Enter Immediate JavaScript commands by typing a function name followed by () to call the
function

– if the function takes arguments then add them between () e.g. (arg1, arg2)

• Typing a function name at the console without () will tell you information about the function
but will not call it
• Add code to the running application by creating variables or functions from the console - don’t
use the same names as the existing app, unless you want to overwrite the app code
• Console can be used in any of the Dev tools tabs by pressing esc
• when you get the developer console up, sometimes you’ll have to refresh the page, when the
console is up, to have access to the game objects
• code completion in the console can help identify functions on objects
• type object names into the console for a tree view of the variables and methods
• always assign setInterval to a variable so you can switch it off when you need to
• use jsbeautifier.org when writing code
• use jscompress.com to make it a one liner
• use jslint.com to help identify errors

66 Alan Richardson
Hacking JavaScript EvilTester.com

About The Author

Alan Richardson has more than twenty years of professional IT experience, working as a Programmer,
in Marketing and Developer Relations and at every level of the testing hierarchy from Tester through to
Head of Testing.

Author of the books “Dear Evil Tester”, “Automating and Testing a REST API”, “Java For Testers” and “Se-
lenium Simplified”. Alan also has created online training courses to help people learn Java, JavaScript,
Technical Web Testing and Selenium WebDriver with Java.

Alan also works as an independent Software and Marketing consultant.

• EvilTester.com,
• CompendiumDev.co.uk.

Alan posts information and videos regularly to social media on:

• Linkedin - linkedin.com/in/eviltester
• Twitter - twitter.com/eviltester
• Github - github.com/eviltester
• Youtube - youtube.com/c/eviltester
• Instagram - instagram.com/eviltester
• Facebook - facebook.com/eviltester
• Pinterest - pinterest.com/eviltester

And/or sign up to our email newsletter:

• https://www.eviltester.com/page/emaillist

And if you are serious about improving your craft and want exclusive daily posts then join the Evil Tester
Patreon Programme and gain access to exclusive posts, videos and courses:

• https://www.patreon.com/eviltester

Alan has online Training related to JavaScript and Technical Testing:

• Technical Web Testing 101 course


• eviltester.com/page/onlinetraining/courses/

Copyright Alan Richardson, Compendium Developments Ltd 2021

Alan Richardson 67

You might also like