In v4.14+ Grouper has better attributes in the UI HTML DOM to navigate programmatically.  The playwright library will be available in the container by setting an environment variable

Playwright will be an option to run inside of Grouper to make scripts that can validate the UI.

Methods will be available to perform certain actions in the UI in a way that is easy to script and will survive upgrades.

These methods are idempotent, so if the state is already set, then it is still a success.  If there is a problem then 

Demo movie

Use the Playwright recorder to simulate a log in or other purposes


CategoryActionClass
DaemonView errorsGrouperUiBrowserDaemonViewErrors
GeneralVerify versionGrouperUiBrowserGeneralVerifyVersion
GroupFind groupGrouperUiBrowserGroupFinder
Create groupGrouperUiBrowserGroupCreate
Edit groupGrouperUiBrowserGroupEdit
Delete groupGrouperUiBrowserGroupDelete
GSH templateRun templateGrouperUiBrowserTemplateRun
Custom UIView custom UIGrouperUiBrowserCustomUiView
MembershipFind membershipGrouperUiBrowserMembershipFinder
Add membershipGrouperUiBrowserMembershipAdd
Remove membershipGrouperUiBrowserMembershipRemove
ProvisioningAssign group provisionableGrouperUiBrowserProvisioningAssignGroup
Remove group provisionableGrouperUiBrowserProvisioningRemoveGroup

DOM attributes and standards

  1. For these methods there will be strong HTML attributes to use for CSS selectors
  2. Selectors are unique in a page
  3. Externalized text will not be used
  4. Prefer to use the "id" of the HTML element
  5. Custom grouper attributes are added to find html elements. (start with "data-gr-" )

    <a href="" data-gr-browse-folder-name="some:folder:name">...</a>
  6. Full paths will be used
  7. Display names will not be used
  8. Values will be escaped
  9. Methods will start by navigating to the main page
  10. Each click will validate that the UI changed
  11. Hidden HTML elements can be used
  12. These operations will run as GrouperSystem

Using these methods

  1. Setup some Playwright objects

    import com.microsoft.playwright.Browser;
    import com.microsoft.playwright.BrowserType;
    import com.microsoft.playwright.Page;
    import com.microsoft.playwright.Playwright;
    import com.microsoft.playwright.options.AriaRole;
    import edu.internet2.middleware.grouper.app.browser.*;
    
        Playwright playwright = Playwright.create();
        BrowserType chromium = playwright.chromium();
        Browser browser = chromium.launch(new BrowserType.LaunchOptions().setHeadless(true));
        Page page = browser.newPage();
        GrouperPage grouperPage = new GrouperPage();
        grouperPage.setPage(page);
      
  2. Navigate to the Grouper being tested

    // either use the built in config for the Grouper UI
    String uiUrl = GrouperConfig.retrieveConfig().propertyValueStringRequired("grouper.ui.url");
    
    // or hard code a url or use another config
    String uiUrl = "https://grouper.institution.edu";
    
    // note this defaults to grouper.properties grouper.ui.url 
    // so you do not need to set this if testing this env
    grouperPage.assignUrl(uiUrl);
    
    // note this is the default so you probably do not need to do this
    grouperPage.assignContext("/grouper");
    
    page.navigate(grouperPage.getUrl());
  3. Authenticate to the UI (e.g. with a test account).  Note you need to record this with selenium (and set the language to Java), or look at the DOM of your login screens

        page.getByLabel("Username").click();
        page.getByLabel("Username").fill("someTestUserName");
        page.getByLabel("Username").press("Tab");
        page.getByLabel("Password", new Page.GetByLabelOptions().setExact(true)).click();
        page.getByLabel("Password", new Page.GetByLabelOptions().setExact(true)).fill(GrouperConfig.retrieveConfig().propertyValueStringRequired("someTestUserName.pass"));
        page.getByLabel("Password", new Page.GetByLabelOptions().setExact(true)).press("Enter");
        
        // does your test account have duo?  accept the push
        page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("No, other people use this")).click();
    
    
  4. Call the API methods above

    import edu.internet2.middleware.grouper.grouperUi.browser.*;
    
    // add a user to a group
    new GrouperUiBrowserMembershipAdd().assignGrouperPage(grouperPage).
       assignGroupName("a:b:c").assignSubjectId("10021368").assignSubjectSourceId("schoolPerson").browse();
    
    // make a group provisionable
    new GrouperUiBrowserProvisioningAssignGroup().assignGrouperPage(grouperPage).
       assignGroupName("a:b:c").assignProvisionerConfigId("myLdapProvisioner").browse();
    
    // etc
  • No labels