Nice idea, @hitchdev
Thanks! And thank you for really engaging with the idea. I do appreciate it.
Okay I’m seeing a few things here that are just tell me we are using different terminology or just shifting the selectors from code into config or metadata? Is that right?
Yes, that’s exactly it.
You mention “selector debt”, I mean if you have no problem with your debt, is moving it into a YAML file going to make life better for engineers?
Maybe. Two reasons:
-
If the selectors are no longer spread out all across the code base and are consolidated in a few files you can now see all of the selectors at a glance. That makes it easy to spot general problems and to do general maintenance - e.g. a front end developer could clean it up by adding IDs to interacted with elements and altering the selectors without having to change any tests.
-
It opens up a new use case - giving scores to selectors and aggregating those scores. For example “//xpath/[0]/1/a/lot/of//rubbish[@xyz=43431]” could be given a score of 0.1 because it’s got flakiness written all over it and “#next-button” could be given a score of 1 because ID selectors are are about as solid as you can get. A script can give your code base an average of 0.85 (good) or 0.3 (not good). It could list the selectors by order of “problematicness”.
2 is just an idea for now, but I’m interested in pursuing it a bit further.
To me this is a code cognitive “load” because “login” is no longer a static, it’s only possible to detect typos in variations of page names or missing pages at runtime now - is that intended?
It’s not intentional, and I would like to prevent it. I’m very keen on type safety and would love for this to fail quickly with a typo.
I think it would be possible to use page.ok.click() by dynamically constructing classes from the pages and returning page as an object more - exactly as you suggest in your second post. I’ll have a long think about this.
I’m assuming you can support composition of pages using this model? How would a person compose pages? For example if a new login page was added that was supporting federation (Google etc) type buttons instead of username + password fields? Can config-driven page object creation still handle that kind of product change?
Wouldn’t that just mean adding a new selector for the new “log in with google button” and writing a new story that uses that?
What exactly do you mean by composition of pages?
I’m not even sure I ever ever want to type pcm.element(“ok”) , because ‘ok’ is a constant and itself becomes problematic from a DRY perspective.
Why so?
I’m probably sounding mega critical,
No, mega critical is exactly what I want, thank you.
but that’s only because I’m working to a platform agnostic page object model where elements on pages on different platforms or on compact screen sizes change selector.
What’s the scenario you are thinking of here? I have some pages which appear very differently on, say, phone and PC but while some elements might disappear or resize selectors generally remain the same.
notice how i converted element('ok) into button_ok() to imply that a thing is a button not an edit box. This was super helpful whenever things needed to be smarter when a control was really an image not a button, or not an edit box. So the config could actually tell if an element was supposed to be modifiable or no - for example radio-button lists get much easier, but also more complicated once they are dynamic. Being able to either diss-allow in your product policy radio buttons in your UI or make test code deal with dynamic radio buttons becomes a time sink if you cannot get some power back.
Can you give an example use case here? I’m not really sure why you’d need do use “page.button_ok.click()” instead of “page.ok.click()”.
Whether or not it it’s an image or a text box or a radio button it’s still a thing with a selector which you can click. If you try to modify something which is not modifiable then, well, the test will fail.