From 93080a30a22208f92b99779905790154406ae80a Mon Sep 17 00:00:00 2001 From: DavertMik Date: Tue, 31 Mar 2026 16:28:06 +0300 Subject: [PATCH 1/2] fix: return plugin-injected functions directly from container instead of wrapping in non-callable Proxy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 4.x ESM migration changed Container.support(name) to always go through the proxy, which wraps values in lazyLoad() — a Proxy designed for page objects (property access), not callable functions. This broke the auth plugin's loginAs/login injection since the returned Proxy has no apply trap. Also fixes missing-key detection in inject.js (was never firing because lazyLoad always returns a truthy Proxy). Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/container.js | 9 ++++++++- lib/mocha/inject.js | 2 +- test/unit/container_test.js | 11 +++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/container.js b/lib/container.js index 6bf89ba92..cae94a772 100644 --- a/lib/container.js +++ b/lib/container.js @@ -150,7 +150,9 @@ class Container { if (!name) { return container.proxySupport } - // Always return the proxy to ensure MetaStep creation works + if (typeof container.support[name] === 'function') { + return container.support[name] + } return container.proxySupport[name] } @@ -600,6 +602,8 @@ function createSupportObjects(config) { let value if (container.sharedKeys.has(prop) && prop in container.support) { value = container.support[prop] + } else if (prop in container.support && typeof container.support[prop] === 'function') { + value = container.support[prop] } else { value = lazyLoad(prop) } @@ -614,6 +618,9 @@ function createSupportObjects(config) { if (container.sharedKeys.has(key) && key in container.support) { return container.support[key] } + if (key in container.support && typeof container.support[key] === 'function') { + return container.support[key] + } return lazyLoad(key) }, }, diff --git a/lib/mocha/inject.js b/lib/mocha/inject.js index 3266a6841..fbed79e7f 100644 --- a/lib/mocha/inject.js +++ b/lib/mocha/inject.js @@ -30,7 +30,7 @@ const getInjectedArguments = async (fn, test, suite) => { testArgs[key] = test.inject[key] continue } - if (!objects[key]) { + if (!(key in objects)) { throw new Error(`Object of type ${key} is not defined in container`) } testArgs[key] = container.support(key) diff --git a/test/unit/container_test.js b/test/unit/container_test.js index 1a3dd0a89..0a7f4dbee 100644 --- a/test/unit/container_test.js +++ b/test/unit/container_test.js @@ -287,6 +287,17 @@ describe('Container', () => { expect(container.support('userPage')).is.ok expect(container.support('userPage').login).is.eql('#login') }) + + it('should be able to add and retrieve a function as a support object', async () => { + await container.create({}) + const loginFunction = async name => `logged in as ${name}` + container.append({ support: { loginAs: loginFunction } }) + expect(container.support('I')).is.ok + const loginAs = container.support('loginAs') + expect(loginAs).to.be.a('function') + const result = await loginAs('admin') + expect(result).to.eql('logged in as admin') + }) }) describe('TypeScript support', () => { From 83a6a1dea9b1d552c44fd4de4712d5613665ff8c Mon Sep 17 00:00:00 2001 From: DavertMik Date: Wed, 1 Apr 2026 03:24:16 +0300 Subject: [PATCH 2/2] revert: inject.js missing-key check change that broke I injection The `!(key in objects)` check used the proxy's `has` trap which doesn't include keys added directly to container.support (like the Actor `I` from createActor). Reverting to the original `!objects[key]` check. Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/mocha/inject.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mocha/inject.js b/lib/mocha/inject.js index fbed79e7f..3266a6841 100644 --- a/lib/mocha/inject.js +++ b/lib/mocha/inject.js @@ -30,7 +30,7 @@ const getInjectedArguments = async (fn, test, suite) => { testArgs[key] = test.inject[key] continue } - if (!(key in objects)) { + if (!objects[key]) { throw new Error(`Object of type ${key} is not defined in container`) } testArgs[key] = container.support(key)