The infrastructure I'm working with originally handled the URLs the way the Site Prism documentation suggested: the domain was handled by setting Capybara.app_host
, and the pages themselves called set_url
with a relative path.
It turns out that some pages on the production site have a subdomain, like members.mycompany.com
rather than www.mycompany.com
. The tests also need to be able to run on test environments with different domains entirely, and in the test environments there are no subdomains at all, even for those pages that do have the subdomain in the production site. So putting the full URL into each SitePrism::Page
is not an option.
I believed that the best option was to stop using Capybara.app_host
entirely, and create a URL builder that would use the state of the environment (i.e. :test
or :production
), the relative path to the page, and a flag indicating whether or not the page was part of the production subdomain. Something like:
def get_url(relative_path, subdomain_flag=false)
case Environment.get_environment
when :test
domain = "https://testmachine.localenvironment.com"
when :production
if subdomain_flag
domain = "https://members.mycompany.com"
else
domain = "https://www.mycompany.com"
end
end
return "#{domain}" + "#{relative_path}"
end
I had hoped that I could use get_url
in each of my SitePrism::Page
objects to generate the full URL without the need for Capybara.app_host
, like so:
class LoginPage < SitePrism::Page
set_url get_url("/login")
...
end
class MemberPage < SitePrism::Page
set_url get_url("/mypage", true)
...
end
If the Environment were :test
, I'd expect the LoginPage
to load https://testmachine.localenvironment.com/login
and MemberPage
to load https://testmachine.localenvironment.com/mypage
. If the Environment were :production
, I'd expect LoginPage
to load https://www.mycompany.com/login
and MemberPage
to load https://members.mycompany.com/mypage
.
I believe the code in my get_url
method does what I think it should do, and I also believe that the Environment object I created is having its state set to the proper environment prior to the pages' #load
method being called in the test. Sadly, when I try to load my SitePrism::Page
objects, the environment value that gets picked up by get_url
is always the default value from the Environment object (which is :test
). As a result, it ends up loading the test environment URL even if I'm trying to execute against production.
It feels like the set_url
part of each SitePrism::Page
object is evaluated before the SitePrism::Page
objects are instantiated, and I can't seem to find a way to get my initialization of the Environment to happen prior to it. I'm new to Ruby so I'm hoping I'm just misunderstanding the order or hierarchy that these things are loading in, and that it's not difficult to correct. Can anyone identify what's wrong with my attempt, or, if there is a better way to handle this situation, point me to what that better way is?
Yes, those
set_url
calls are being evaluated when the class is being defined, in other words, when your file is first required.The simple solution is to make sure that your
Environment
configuration is initialised before the page objects are required.Note that the SitePrism docs say that
set_url
is only needed when navigating directly to a page:For verifying that you're on a page, you can use a regular expression instead. See https://github.com/natritmeyer/site_prism#verifying-that-a-particular-page-is-displayed for an example of running in multiple environments.