browser_tester 1.5.0

Deterministic lightweight browser runtime for Rust tests
Documentation
use super::*;

#[test]
fn generator_function_constructor_from_literal_builds_generator_functions() -> Result<()> {
    let html = r#"
        <button id='run'>run</button>
        <p id='out'></p>
        <script>
          document.getElementById('run').addEventListener('click', () => {
            const GeneratorFunction = (function* () {}).constructor;
            const byNew = new GeneratorFunction(`
              yield 'a';
              yield 'b';
              yield 'c';
            `);
            const byCall = GeneratorFunction('yield 1; yield* [2, 3];');
            const empty = GeneratorFunction();

            let letters = '';
            for (const value of byNew()) {
              letters += value;
            }
            const numbers = byCall().toArray().join(',');
            const emptyLen = empty().toArray().length;
            const tag = GeneratorFunction.prototype[Symbol.toStringTag];

            document.getElementById('out').textContent =
              letters + '|' + numbers + '|' + emptyLen + '|' + tag;
          });
        </script>
        "#;

    let mut h = Harness::from_html(html)?;
    h.click("#run")?;
    h.assert_text("#out", "abc|1,2,3|0|GeneratorFunction")?;
    Ok(())
}

#[test]
fn global_generator_function_constructor_surface_and_prototype_chain_work() -> Result<()> {
    let html = r#"
        <button id='run'>run</button>
        <p id='out'></p>
        <script>
          document.getElementById('run').addEventListener('click', () => {
            const sample = function* namedGen() {};
            const byGlobal = GeneratorFunction('yield 1; yield 2;');
            document.getElementById('out').textContent = [
              typeof GeneratorFunction,
              String(window.GeneratorFunction === GeneratorFunction),
              GeneratorFunction.name,
              String(GeneratorFunction.length),
              String(Object.getPrototypeOf(GeneratorFunction) === Function.prototype),
              String(Object.getPrototypeOf(sample) === GeneratorFunction.prototype),
              byGlobal.name,
              String(byGlobal.length),
              String(byGlobal.prototype.constructor === byGlobal),
              String(byGlobal.toString().includes('__bt_function_ref__(')),
              String(byGlobal().toArray().join(',')),
              String(sample.constructor === GeneratorFunction)
            ].join('|');
          });
        </script>
        "#;

    let mut h = Harness::from_html(html)?;
    h.click("#run")?;
    h.assert_text(
        "#out",
        "function|true|GeneratorFunction|1|true|true|anonymous|0|true|true|1,2|true",
    )?;
    Ok(())
}

#[test]
fn generator_function_native_source_text_and_hidden_surface_work() -> Result<()> {
    let html = r#"
        <button id='run'>run</button>
        <p id='out'></p>
        <script>
          document.getElementById('run').addEventListener('click', () => {
            const ctorText = GeneratorFunction.toString();
            const iterProto = GeneratorFunction.prototype.prototype;

            function forInKeys(value) {
              let out = '';
              for (const key in value) {
                out += key + ',';
              }
              return out || 'empty';
            }

            document.getElementById('out').textContent = [
              String(ctorText.includes('[native code]')),
              String(ctorText.includes('GeneratorFunction')),
              String(ctorText === Function.prototype.toString.call(GeneratorFunction)),
              String(ctorText === String(GeneratorFunction)),
              String(ctorText === new String(GeneratorFunction).valueOf()),
              String(Object.keys(GeneratorFunction).length),
              String(Object.keys(GeneratorFunction.prototype).length),
              String(Object.keys(iterProto).length),
              String(Object.keys({ ...GeneratorFunction.prototype }).length),
              String(Object.keys({ ...iterProto }).length),
              forInKeys(GeneratorFunction.prototype),
              forInKeys(iterProto),
              JSON.stringify(iterProto)
            ].join('|');
          });
        </script>
        "#;

    let mut h = Harness::from_html(html)?;
    h.click("#run")?;
    h.assert_text("#out", "true|true|true|true|true|0|0|0|0|0|empty|empty|{}")?;
    Ok(())
}