RegEx to assert HTML in a response body

I have this line return within HTML in a response body;
<script type="text/javascript" src="/main.fed3fbbceb96763d430c.chunk.js"></script>

The string is a hash of letters and numbers and I’m trying to assert that the value in “src” is

/main.REGEX.chunk.js

I have been reading other posts and the best I have come up with is this;

const response = pm.response.text();
let my_regex = new RegExp(pm.globals.get('regEx'));
pm.test("Body matches string", function () {
    pm.expect(response).to.include(`src="/main.${my_regex}.chunk.js"`);
});

However, it still doesn’t work, can anyone help me alter this to work properly?
Any guidance would be appreciated.

I’m not sure from your original post whether you already know the hexadecimal string fed3ff.. or if that’s what you’re trying to find.

If it’s the first case, where you already know the pattern, then this should work:

// save response text
let text = pm.response.text()

// grab your pattern from global variables
let myPattern = pm.globals.get('regEx')

pm.test("body contains regex", function() {
  // detect if the pattern exists in the text
  pm.expect(text).to.include(`main.${myPattern}.chunk.js`)
})

If you’re trying to FIND the pattern based on what’s in the text, something like this should work:

let text = `... <script type="text/javascript" src="/main.fed3fbbceb96763d430c.chunk.js"></script> ...`

myRe = new RegExp('main\.([^.]*)\.chunk\.js', 'g');
myArray = myRe.exec(text)
pm.test("body contains regex and saves it", function() {
  pm.expect(myArray.length).to.be.gte(2)
  pm.globals.set('regEx', myArray[1])
})

Thank you for your help @iandouglas

It was the second option that I was aiming for. I have taken your code and tweaked it to work with a try-catch so that I can run multiple checks for different strings/regex.
(There’s only 1 at the moment, but the important thing is it works!)

Here is the code for anyone else that encounters the same…

const text = pm.response.text();
myRe = new RegExp('main\.([^.]*)\.chunk\.js', 'g');
myArray = myRe.exec(text);
let count = 0;

pm.test("Check for RegEx", () => {
    try {
        pm.expect(myArray.length).to.be.gte(2);
        pm.test("Body contains regex");
    } catch (e) {
        pm.test("Body doesn't contain regex", () => {
            throw new Error(e.message)
        }), count++;
    }
    if (count > 0) {
        console.error("There are failures within the above checks, please check...");
        pm.expect.fail("There are " + count + " failures within the above checks, please check...");
    }
});

Info about .exec
If the match succeeds, the exec() method returns an array (with extra properties index, input, and if the d flag is set, indices; see below) and updates the lastIndex property of the regular expression object. The returned array has the matched text as the first item, and then one item for each parenthetical capture group of the matched text. If the match fails, the exec() method returns null, and sets lastIndex to 0.

Hi again @iandouglas

I’ve been playing around with this code and it’s working great, but I was wondering if you could clarify what the 'g' part of the code this line does?
myRe = new RegExp('main\.([^.]*)\.chunk\.js', 'g');

I have seen examples that use ‘i’ too … but I can’t seem to find a description of what it does.

Cheers

Hey!

So the g pretty much just asks it to match against all possible substrings in a string.

Here’s an MDN link that might help explain better :smile:

Usually when I write/test regex, I use something like https://regex101.com/ which gives some excellent explanations for what things do.

1 Like

Cheers @kevin-postman, the description on there;

The " g " flag indicates that the regular expression should be tested against all possible matches in a string

Was just what I was looking for!!
(ironically I was on that website I just hadn’t spotted that!)

Thank you!

1 Like

With regular expressions you can set flags to run once, or run “globally” (aka, find multiple matches). I tend to use “global” with most of what I do with regex, so it’s just kind of a default for me :slight_smile:

You’re welcome to remove the ‘g’ and that will only find the first match.

1 Like