testUsingWebGL(name, method, needsFloatSupport=false) {
        let wrappedMethod = (caseName, status, subNeedFloats) => {
            if (subNeedFloats && !canTestFloatShaders()) {
                let msg = `Skipping ${this.name}.${caseName} due to lack of WebGL float texture support.`;
                console.warn(msg);
                status.log.push(msg);
                assertThat(undefined); // Cancel 'no assertion' warning.
                return;
            }

            if (!isWebGLSupportPresent()) {
                let msg = `Skipping ${this.name}.${caseName} due to lack of WebGL support.`;
                console.warn(msg);
                status.log.push(msg);
                assertThat(undefined); // Cancel 'no assertion' warning.
                return;
            } else if (isOnlyPartialWebGLSupportPresent()) {
                status.warn_only = true;
                status.ignore_warn_only_on_success = true;
                status.warn_failure_message = `Ignoring ${this.name}.${caseName} failure due to lack of WebGL support.`;
                status.warn_show_error = true;
            }

            let preTexCount = WglTexturePool.getUnReturnedTextureCount();
            method(status);
            let gain = WglTexturePool.getUnReturnedTextureCount() - preTexCount;
            if (gain > 0) {
                throw new DetailedError("Unreturned textures.", {unreturned_increase: gain});
            }
            if (gain < 0) {
                throw new DetailedError("Extra returned textures.", {extra_returns: -gain});
            }

            status.wasWebGLTest = true;
        };

        this.test(name + '[byte-coder]', status => {
            if (isFirstByteCoderWebGlTest) {
                changeShaderCoder(SHADER_CODER_BYTES);
                isFirstByteCoderWebGlTest = false;
            }
            wrappedMethod(name + '[byte-coder]', status, needsFloatSupport)
        }, false);

        this.test(name + '[float-coder]', status => {
            if (isFirstFloatCoderWebGlTest) {
                changeShaderCoder(SHADER_CODER_FLOATS);
                isFirstFloatCoderWebGlTest = false;
            }
            wrappedMethod(name + '[float-coder]', status, true);
        }, true);
    }
@param {!string} name
@param {!function(!{ warn_only: !boolean|!string })} method
@param {!boolean=false} needsFloatSupport