Skip to content

Conversation

kobenguyent
Copy link
Collaborator

3.7.5

❤️ Thanks all to those who contributed to make this release! ❤️

✨ Features

Backward Compatible Boolean Configuration

// codecept.conf.js
exports.config = {
  maskSensitiveData: true, // Uses built-in patterns for common sensitive data
  // ... other config
}

Advanced Custom Patterns Configuration

// codecept.conf.js
exports.config = {
  maskSensitiveData: {
    enabled: true,
    patterns: [
      {
        name: 'Email',
        regex: /(\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b)/gi,
        mask: '[MASKED_EMAIL]'
      },
      {
        name: 'Credit Card',
        regex: /\b(?:\d{4}[- ]?){3}\d{4}\b/g,
        mask: '[MASKED_CARD]'
      },
      {
        name: 'Phone Number',
        regex: /(\+?1[-.\s]?)?\(?([0-9]{3})\)?[-.\s]?([0-9]{3})[-.\s]?([0-9]{4})/g,
        mask: '[MASKED_PHONE]'
      }
    ]
  },
  // ... other config
}

## Example Output

With the above configuration, sensitive data is automatically masked:

**Before:**

Given I have user email "[email protected]"
And I have credit card "4111 1111 1111 1111"
And I have phone number "+1-555-123-4567"


**After:**

Given I have user email "[MASKED_EMAIL]"
And I have credit card "[MASKED_CARD]"
And I have phone number "[MASKED_PHONE]"
exports.config = {
  helpers: {
    Playwright: {
      url: 'http://localhost',
      browser: 'chromium',
      customLocatorStrategies: {
        byRole: (selector, root) => {
          return root.querySelector(`[role="${selector}"]`);
        },
        byTestId: (selector, root) => {
          return root.querySelector(`[data-testid="${selector}"]`);
        },
        byDataQa: (selector, root) => {
          const elements = root.querySelectorAll(`[data-qa="${selector}"]`);
          return Array.from(elements); // Return array for multiple elements
        }
      }
    }
  }
}

And used in tests with the same syntax as other locator types:

I.click({byRole: 'button'});           // Find by role attribute
I.see('Welcome', {byTestId: 'title'}); // Find by data-testid
I.fillField({byDataQa: 'email'}, '[email protected]');
plugins: {
  htmlReporter: {
    enabled: true
  }
}

HTML report

Unified API Methods

  • Element Properties: getText(), getAttribute(), getProperty(), getInnerHTML(), getValue()
  • Element State: isVisible(), isEnabled(), exists(), getBoundingBox()
  • Element Interactions: click(), type()
  • Child Element Search: $() and $$() methods for finding sub-elements
  • Native Access: getNativeElement() and getHelper() for advanced operations

Updated Helper Methods

  • grabWebElement() and grabWebElements() now return WebElement instances instead of native elements
  • Added missing grabWebElement() method to WebDriver and Puppeteer helpers
  • Maintains backward compatibility through getNativeElement() method
// Works consistently across all helpers
const element = await I.grabWebElement('#button');
const text = await element.getText();
const childElements = await element.$$('.child');
await element.click();

// Element searching within elements
const form = await I.grabWebElement('#contact-form');
const nameInput = await form.$('#name');
await nameInput.type('John Doe');

🐛 Bug Fixes

@thomashohn
Copy link
Contributor

@kobenguyent Looks good to me - this one looks weird "test file hyperlink clickable" and won't work

@kobenguyent kobenguyent merged commit 3ba96d1 into 3.x Sep 22, 2025
14 of 16 checks passed
@kobenguyent kobenguyent deleted the release-3.7.5 branch September 22, 2025 09:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants