{"id":20050092,"url":"https://github.com/mithriljs/mithril-query","last_synced_at":"2025-10-05T14:14:28.941Z","repository":{"id":21147681,"uuid":"24449985","full_name":"MithrilJS/mithril-query","owner":"MithrilJS","description":"Query mithril virtual dom for testing purposes","archived":false,"fork":false,"pushed_at":"2025-08-11T18:09:32.000Z","size":298,"stargazers_count":106,"open_issues_count":3,"forks_count":34,"subscribers_count":20,"default_branch":"master","last_synced_at":"2025-09-18T18:21:59.680Z","etag":null,"topics":["javascript","mithril","selector"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MithrilJS.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"open_collective":"mithriljs"}},"created_at":"2014-09-25T08:30:45.000Z","updated_at":"2025-08-11T18:09:36.000Z","dependencies_parsed_at":"2024-01-23T21:17:41.748Z","dependency_job_id":"7548b9b0-d51f-44ba-9ba8-725bfafa40cf","html_url":"https://github.com/MithrilJS/mithril-query","commit_stats":{"total_commits":249,"total_committers":25,"mean_commits":9.96,"dds":0.2570281124497992,"last_synced_commit":"facf7ce84bacf3e2e9bb413ecd56d9f3cd4aa505"},"previous_names":["stephanhoyer/mithril-query"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/MithrilJS/mithril-query","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MithrilJS%2Fmithril-query","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MithrilJS%2Fmithril-query/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MithrilJS%2Fmithril-query/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MithrilJS%2Fmithril-query/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MithrilJS","download_url":"https://codeload.github.com/MithrilJS/mithril-query/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MithrilJS%2Fmithril-query/sbom","scorecard":{"id":95100,"data":{"date":"2025-08-11","repo":{"name":"github.com/MithrilJS/mithril-query","commit":"e748bbf2963c66e0147acc9be23365f4603097a7"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.2,"checks":[{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":1,"reason":"Found 3/24 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":1,"reason":"1 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: github.com/MithrilJS/.github/SECURITY.md:1","Info: Found linked content: github.com/MithrilJS/.github/SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: github.com/MithrilJS/.github/SECURITY.md:1","Info: Found text in security policy: github.com/MithrilJS/.github/SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":6,"reason":"4 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 9 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-15T08:48:48.921Z","repository_id":21147681,"created_at":"2025-08-15T08:48:48.922Z","updated_at":"2025-08-15T08:48:48.922Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278464330,"owners_count":25991182,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-05T02:00:06.059Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","mithril","selector"],"created_at":"2024-11-13T11:54:03.643Z","updated_at":"2025-10-05T14:14:28.909Z","avatar_url":"https://github.com/MithrilJS.png","language":"JavaScript","readme":"# mithril-query\n\n[![Gitter](https://img.shields.io/badge/gitter-join_chat-1dce73.svg?logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB4PSIwIiB5PSI1IiBmaWxsPSIjZmZmIiB3aWR0aD0iMSIgaGVpZ2h0PSI1Ii8%2BPHJlY3QgeD0iMiIgeT0iNiIgZmlsbD0iI2ZmZiIgd2lkdGg9IjEiIGhlaWdodD0iNyIvPjxyZWN0IHg9IjQiIHk9IjYiIGZpbGw9IiNmZmYiIHdpZHRoPSIxIiBoZWlnaHQ9IjciLz48cmVjdCB4PSI2IiB5PSI2IiBmaWxsPSIjZmZmIiB3aWR0aD0iMSIgaGVpZ2h0PSI0Ii8%2BPC9zdmc%2B\u0026logoWidth=8)](https://gitter.im/MithrilJS/mithril-query?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n[![Build Status](https://travis-ci.org/MithrilJS/mithril-query.svg?branch=master)](https://travis-ci.org/MithrilJS/mithril-query)\n[![rethink.js](https://img.shields.io/badge/rethink-js-yellow.svg)](https://github.com/rethinkjs/manifest)\n[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)\n\nQuery mithril virtual dom for testing purposes\n\n## Installation\n\n    npm install mithril-query --save-dev\n\n## Setup\n\nIn order to run tests in mithril 2.x we need to do some dom-mocking for the renderer.\n`mithril-query` will try to do this mocking for you, if it can't find the required globals, but this\nmight not work properly due to module loading order. If you load mithril-query before everything else\nit should work as expected.\n\nIn any other case, this can be done manually by calling the `ensureGlobals` helper upfront (e. G. by adding if into a 'setup' file in your 'mocha' tests).\n\n```js\nrequire('mithril-query').ensureGlobals()\n```\n\n## Changes from version 3.x to 4.x\n\n#### Root state access\n\n... is gone, since `mithril` does not provide a way to access it\n\n#### Booleans\n\n... are now rendered as empty strings, like mithril does, because, well, mithril renders\n\n#### Lifecycles\n\n... are now fully supported, including synthetic DOM elements 🎉\n\n#### find/first\n\n... are now returning DOM elements instead of vdom nodes.\n\n#### Custom events\n\n... aren't supported anymore. Feel free to file a ticket, if you want them back.\n\n## Usage\n\nYou can run this tests server side or use browserify and run them in browsers.\n\n```js\nconst m = require('mithril')\n\nmodule.exports = {\n  view: function() {\n    return m('div', [\n      m('span', 'spanContent'),\n      m('#fooId', 'fooContent'),\n      m('.barClass', 'barContent'),\n    ])\n  },\n}\n```\n\n```js\n/* eslint-env mocha */\nconst mq = require('mithril-query')\nconst simpleModule = require('./simple')\n\ndescribe('simple module', function() {\n  it('should generate appropriate output', function() {\n    var output = mq(simpleModule)\n    output.should.have('span')\n    output.should.have('div \u003e span')\n    output.should.have('#fooId')\n    output.should.have('.barClass')\n    output.should.have(':contains(barContent)')\n    output.should.contain('barContent')\n  })\n})\n```\n\nRun the test with\n\n    mocha simple.test.js\n\n## API\n\n### Initialise\n\nFirst call `mithril-query` with either a vnode or a component. You can call it\nwith one extra argument which will be used as `attrs` in the component case.\n\n```js\nvar mq = require('mithril-query')\n\n// plain vnode\nvar out = mq(m('div'))\n\n// object component\nvar myComponent = {\n  view: function({ attrs }) {\n    return m('div', attrs.text)\n  },\n}\nvar out = mq(myComponent, { text: 'huhu' })\n\n// closure component\nfunction myComponent() {\n  return {\n    view: function({ attrs }) {\n      return m('div', attrs.text)\n    },\n  }\n}\nvar out = mq(myComponent, { text: 'huhu' })\n```\n\n### Query API\n\nAs you can see `mq` returns an `out`-Object which has the following test-API.\n\n- `out.first(selector)` – Returns the first element that matches the selector (think `document.querySelector`).\n- `out.find(selector)` – Returns all elements that match the selector (think `document.querySelectorAll`).\n- `out.has(selector)` –  Returns `true` if any element in tree matches the selector, otherwise `false`.\n- `out.contains(string)` – Returns `true` if any element in tree contains the string, otherwise `false`.\n- `out.log(selector, [logFN])` – Small helper function to log out what was selected. Mainly for debugging\n  purposes. You can give an optional function which is called with the result.\n  It defaults to HTML-Pretty-Printer ([pretty-html-log](https://www.npmjs.com/package/pretty-html-log)] that logs the HTML-representation to `stdout`.\n\nYou can use these nice assertions. They throw errors if they're not fulfilled.\nSee the example in the example folder.\n\n- `out.should.have([count], selector)`\n\nThrows if no element is found with selector. If `count` is given, it throws if\ncount does not match.\n\n- `out.should.not.have(selector)` – Throws if an element is found with selector.\n- `out.should.have.at.least(count, selector)` – Throws if there a fewer than `count` elements matching the selector\n- `out.should.have([selector0, selector1, selector2])` – Throws there aren't at least one element for each selector.\n- `out.should.contain(string)` – Throws if no element contains `string`.\n- `out.should.not.contain(string)` - Throws if any element contains `string`.\n\n### Event triggering\n\nIt is also possible to trigger element events like `onfocus` and `onclick` and set values on `\u003cinput\u003e`-fields. This allows you to write \"integration tests\" that run also on server side.\n\nAttention: Currently there is no event bubbling supported.\n\n- `out.click(selector, [eventData])` – Runs `onclick` for first element that matches selector. Optional `eventData` is given\n  as to the event constructor. `eventData.redraw = false` is respected.\n- `out.setValue(selector, string, [eventData])` – Runs `oninput` and `onchange` for first element that matches selector.\n- `out.trigger(selector, eventname, [eventData])` – General purpose event triggerer. Calls `eventname` on first matching element.\n\nIt also supports key events\n\n- `out.keydown(selector, keycode, [eventData])` – calls `onkeydown` with `keycode`\n- `out.keydown(selector, keyname, [eventData])` – calls `onkeydown` with keycode mapped from name. Mapping is done with [this lib](https://github.com/npmcomponent/yields-keycode).\n\n`keyup`, `keypress` are supported as well.\n\n### Auto \"Redrawing\"\n\nSince `mithril-query` uses `mithril` on a fake DOM, auto rendering works as expected.\n\nExample:\n\n```js\n  // module code\n  const component = {\n    visible: true\n    oninit({ state }) {\n      state.toggleMe = () =\u003e (state.visible = !state.visible)\n    },\n    view({ state }) {\n      return m(\n        state.visible ? '.visible' : '.hidden',\n        { onclick: state.toggleMe},\n        'Test'\n      )\n    },\n  }\n\n\n  // actual test\n  out = mq(component)\n  out.should.have('.visible')\n  out.click('.visible')\n  out.should.not.have('.visible')\n  out.should.have('.hidden')\n  out.click('.hidden', { redraw: false })\n  out.should.have('.hidden')\n```\n\nAs you can see, you can prevent auto redraw by providing a `redraw: false` as last\nargument to `click` method.\n\nYou can also manually trigger redraw:\n\n```javascript\nvar out = mq(module)\nout.should.have('.visible')\nout.redraw()\n```\n\n### helpers\n\nIf you need to access the rendered root element you can simply access it with\n\n```javascript\nout.rootEl\n```\n\n### `onremove` handling\n\nTo trigger `onremove`-handlers of all initialized components, just call `out.onremove()`\n","funding_links":["https://opencollective.com/mithriljs"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmithriljs%2Fmithril-query","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmithriljs%2Fmithril-query","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmithriljs%2Fmithril-query/lists"}