2

I'm looking for a way to create unique and deterministic test id's to be used for end-to-end testing. This would mean that running any iteration would produce the exact same id for the exact same component so that tests would have a reliable way to reference an item.

Starting with an example of applying a directive on every button:

@Directive({
    selector: 'button',
})
export class FormControlPropertiesDirective {

    constructor(
        private element: ElementRef,
    ) {
    }
}

Is there any way I could apply an algorithm or use some distinct property of the element to create something deterministic?

4
  • Your question is way too broad. Please limit it to a single issue. Consider providing examples of what you're trying to achieve and what you have tried so far. Commented Jun 28, 2019 at 13:16
  • I don't feel the question is too broad, what i'm looking for is an automated way to mark elements with a unique test id attribute. So far I haven't found anything that remains constant through multiple passes of the angular application. Commented Jun 28, 2019 at 13:39
  • So something like HTML ID attribute ... Commented Jun 28, 2019 at 13:42
  • sure, an id attribute or an arbitrary attribute like [data-test-id], that will be used to target a specific element for end-to-end testing Commented Jun 28, 2019 at 17:29

1 Answer 1

0

If you manage to link your components to a certain model you could use an hash function over that model... an hash function like this (Taken from an answer from this question Simple (non-secure) hash function for JavaScript? and transformed it as a simple function):

 hashObject(o: any) {
    var l = 2;
    var i, c, r = [];
    for (i = 0; i < l; i++)
        r.push(i * 268803292);
    function stringify(o) {
        var i, r;
        if (o === null) return "n";
        if (o === true) return "t";
        if (o === false) return "f";
        if (o instanceof Date) return "d:" + o.toString();
        i = typeof o;
        if (i === "string") return "s:" + o.replace(/([\\\\;])/g, "\\$1");
        if (i === "number") return "n:" + o;
        if (o instanceof Function) return "m:" + o.toString().replace(/([\\\\;])/g, "\\$1");
        if (o instanceof Array) {
            r = [];
            for (i = 0; i < o.length; i++)
                r.push(stringify(o[i]));
            return "a:" + r.join(";");
        }
        r = [];
        for (i in o) {
            r.push(i + ":" + stringify(o[i]));
        }
        return "o:" + r.join(";");
    }
    o = stringify(o);
    for (i = 0; i < o.length; i++) {
        for (c = 0; c < r.length; c++) {
            r[c] = (r[c] << 13) - (r[c] >> 19);
            r[c] += o.charCodeAt(i) << (r[c] % 24);
            r[c] = r[c] & r[c];
        }
    }
    for (i = 0; i < r.length; i++) {
        r[i] = this.toHex(r[i]);
    }
    return r.join("");
}

  toHex(number: number): string {
        var ret = ((number < 0 ? 0x8 : 0) + ((number >> 28) & 0x7)).toString(16) + (number & 0xfffffff).toString(16);
        while (ret.length < 8) ret = "0" + ret;
        return ret;
    }

Or, if you really just need to generate test ids you could use faker.js (https://github.com/marak/Faker.js/). By providing a seed to its data generator you can obtain deterministic results

Sign up to request clarification or add additional context in comments.

1 Comment

I like the faker implementation for seeding a result, the only unknown that remains for me is what to use as a seed. It should be something extractable from the targeted html element that does not ever change over multiple compiles/runs of the application.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.