I often talk about automating tactically and strategically. When we automate tactically we do what it takes to get the job done for us. When we automate strategically we build for the long term.
The same is true for programming tools. We can start small and tactical and scale strategically. In this example I create a Counterstring tool.
Counterstrings
I have written about Counterstrings before:
- Counterstring algorithms
- and I implemented it in my Test Tools Hub
And you can find James Bach’s original writing and work on Counterstrings at satisfice.com
Since I don’t have a tool for creating Counterstrings in the Web I set out to create one.
I thought this would be a good simple tutorial for JavaScript, tactical tooling and eventually strategic tooling (by converting it into a Chrome extension).
A Counterstring is a string like this *3*5*7*9*12*15*
where the *
represent the position in the string of the number immediately proceeding it.
How to write it?
Chrome has “Snippets”
- right click, inspect
- in Sources select the “Snippets” tab
- create a
+ New Snippet
This is a built in JavaScript Editor within your browser.
To see it work type into the snippet:
console.log("hello");
Click the play icon, and your script should run and you’ll see "hello"
written to the console.
To create a Counterstring tool start by creating a function:
function getCounterString(count){
console.log("hello");
}
If you run this, nothing will happen.
But after running it, if you type into the console getCounterString(5)
you should see "hello"
written to the console.
We will make it output a counterstring.
Counterstring generation function
function getCounterString(count){
var counterString = "";
while(count>0){
var appendThis = "*" + count.toString().split("").reverse().join("");
if(appendThis.length>count){
appendThis = appendThis.substring(0,count);
}
counterString = counterString + appendThis;
count = count - appendThis.length;
}
return counterString.split("").reverse().join("");
}
If you run this, nothing will happen.
But after running it, if you type into the console getCounterString(5)
you should see "*3*5*"
written to the console.
How does it work?
Declare a function called getCounterString
which takes one parameter called count
. That is how we are able to specify the length of the counterstring we want when we call the function getCounterString(5)
function getCounterString(count){
Create a String variable which we will build the counterString in:
var counterString = "";
We need to loop around all the values in the counterstring e.g. 5, 3, and 1. So I will decrease the count as we process the values and I’ll use a while
loop to do this e.g. while count is greater than 0, keep building the counterstring.
while(count>0){
Each time I process a count value I will create a string like "*5"
or "*3"
I will append this to the counterString
. But I can’t just write "*13"
because I’m going to reverse the string later so I reverse the number as I create it e.g "*31"
which would be reversed and read from left to right as "13*"
. The way I reverse a string in JavaScript is to .split("").reverse().join("")
which uses split
to convert it to an array, reverse
to reverse it then join
to convert the array back to a String.
var appendThis = "*" + count.toString().split("").reverse().join("");
Another complication is that I can’t just add the number to the String otherwise I’ll end up with "1*"
as my 1 character string, and it isn’t it is two characters. So if the String I want to append is greater than the number of characters left then I only want a part of that string, e.g. a substring.
if(appendThis.length>count){
appendThis = appendThis.substring(0,count);
}
Then I append my number String to the counterstring.
counterString = counterString + appendThis;
Then I decrement ‘count’ by the number of characters I just added to the counterstring.
count = count - appendThis.length;
Then I continue the while loop if count
still has characters to process.
}
Then, finally, I return the reversed counterString.
return counterString.split("").reverse().join("");
}
Refactoring
Since I have repeated code .split("").reverse().join("")
I create a reverseString
method
function reverseString(reverseMe){
return reverseMe.split("").reverse().join("");
}
Which I would call in my getCounterString
function by:
var appendThis = "*" + reverseString(count.toString());
And
return reverseString(counterString);
This would give me a getCounterString
function which I could run from the console, and I could then copy and paste the counterstring - a very basic tool.
Easier to use
var count = window.prompt("Counterstring Length?", "100");
var counterString = getCounterString(count);
console.log(counterString);
The above code creates an input dialog and asks me “Counterstring Length?”, and I can enter the length I want. It stores the value I enter into a variable called count
which it then uses to call the getCounterString
method.
And I print the generated Counterstring to the console, using console.log
to make it easier to copy and paste.
Even easier to use
I can manipulate the DOM, i.e. the Web Page, from JavaScript.
And if I select an input field before running the script then the I can use document.activeElement
to find the input field that I selected and can set the value of that field.
document.activeElement.value=counterString;
If I select an input field, and then run the snippet then the counterstring should be added to the input.
Note: this bypasses HTML max length attribute controls since it injects the text directly into the field Value, and doesn’t type the keys.
Video
I’ve created a video showing all this in action:
Code
And you can find the source code on Github.
If you found this useful then you might be interested in my Online Technical Web Testing 101 course.
If you are interested in writing a Chrome Extension then check out all blog posts in this category Chrome Extension and see the videos in this Chrome Extension Playlist