How do I set the URL for a SitePrism::Page that might have a subdomain?

2.4k views Asked by At

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?

1

There are 1 answers

1
Tim Moore On BEST ANSWER

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:

Note that setting a URL is optional - you only need to set a url if you want to be able to navigate directly to that page. It makes sense to set the URL for a page model of a home page or a login page, but probably not a search results 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.