Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Testwins 0.4.0
# Testwins 0.4.1

**Jedna paczka do testów GUI, scenariuszy TestQL, shell/terminala, osobnych kontraktów API i ciągłej obserwacji.**
To scalone wydanie wcześniejszych Testwins 0.2/0.3 oraz migracji `twin_ux` / Clonerd.
Expand Down Expand Up @@ -45,7 +45,7 @@ Przykład live domyślnie obserwuje **3 trasy x 3 profile x Chromium**, nie trzy
make bootstrap
. .venv/bin/activate
# Alternatywa bez bootstrap, po utworzeniu i aktywowaniu venv:
python -m pip install './dist/testwins-0.4.0-py3-none-any.whl[live,terminal]'
python -m pip install './dist/testwins-0.4.1-py3-none-any.whl[live,terminal]'
python -m playwright install chromium

testwins --version
Expand Down
9 changes: 9 additions & 0 deletions project/ticket-019/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# ticket-019 — Exclude errors/README.md in standards checker, guard optional cv2/numpy/typer test deps, and align version SSOT

## Goal
Exclude `errors/README.md` when collecting error codes in `tools/standards.py` (`B09`), guard optional `cv2`/`numpy`/`typer` imports in `tests/test_extensions.py` and `tests/live/test_live_io.py` and exclude `.worktrees`/`.governance` in `tools/release.py` (`B02`), and align version `0.4.1` SSOT across `README.md`, `verification/summary.json`, and `tests/test_release_contracts.py` (`B03`).

## Acceptance Criteria
1. `tools/standards.py` excludes `README.md` from `errors/*.md` error code discovery.
2. `tests/test_extensions.py` and `tests/live/test_live_io.py` skip cleanly via `pytest.importorskip` when `cv2`, `numpy`, or `typer` is not installed.
3. `VERSION`, `pyproject.toml`, `testwins.__version__`, `README.md`, and `verification/summary.json` all agree on `0.4.1`.
19 changes: 19 additions & 0 deletions project/ticket-019/intent.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"schemaVersion": "1.0.0",
"ticketId": "ticket-019",
"title": "Exclude errors/README.md in standards checker, guard optional cv2/numpy/typer test deps, and align version SSOT",
"owner": "antigravity",
"workstream": "release-and-standards",
"status": "IN_PROGRESS",
"phase": "EDIT",
"allowedPaths": [
"project/ticket-019/**",
"tools/standards.py",
"tools/release.py",
"README.md",
"verification/summary.json",
"tests/test_extensions.py",
"tests/live/test_live_io.py",
"tests/test_release_contracts.py"
]
}
1 change: 1 addition & 0 deletions tests/live/test_live_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ def test_wup_installer_no_overwrite(tmp_path):


def test_wup_typer_adapter_has_watch_status_export_capacity():
pytest.importorskip('typer')
from typer.testing import CliRunner
spec=importlib.util.spec_from_file_location('wup_gui',ROOT/'integrations/wup/overlay/wup/gui_testwins.py');m=importlib.util.module_from_spec(spec);spec.loader.exec_module(m)
r=CliRunner().invoke(m.app,['--help']);assert r.exit_code==0
Expand Down
5 changes: 4 additions & 1 deletion tests/test_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,17 +139,20 @@ def test_vision_invented_selector():
with pytest.raises(ValueError):validate_response({'findings':[f]},{'#real'},400,300)

def test_opencv_actual(screenshot,tmp_path):
pytest.importorskip('cv2')
assert len(contours(screenshot))>0
tpl=tmp_path/'template.png';Image.open(screenshot).crop((25,35,125,105)).save(tpl)
result=match_template(screenshot,tpl);assert result['found'] and result['score']>.99
assert result['box']['x']==25 and result['box']['y']==35
data=analyze(screenshot,tmp_path/'cv.json');assert data['defects']==[] and data['authority']=='none'

def test_uniform_rgb_template_rejected(screenshot,tmp_path):
pytest.importorskip('cv2')
tpl=tmp_path/'constant.png';Image.new('RGB',(20,20),(255,0,0)).save(tpl)
with pytest.raises(ValueError,match='texture'):match_template(screenshot,tpl)

def test_template_larger(screenshot,tmp_path):
pytest.importorskip('cv2')
tpl=tmp_path/'large.png';Image.new('RGB',(401,301),'white').save(tpl)
assert not match_template(screenshot,tpl)['found']

Expand All @@ -160,7 +163,7 @@ def test_nms_class_aware():

def test_yolo_mock_adapter_tiles_and_offsets(tmp_path):
"""Fake detections exercise adapter coordinate logic; no weights/model inference are claimed."""
import numpy as np
np=pytest.importorskip('numpy')
p=tmp_path/'long.png';Image.new('RGB',(400,2000),'white').save(p)
weights=tmp_path/'fake.pt';weights.write_bytes(b'NOT A MODEL')
calls=[]
Expand Down
14 changes: 13 additions & 1 deletion tests/test_release_contracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ async def send(self,*args):return {'metrics':[{'name':'Nodes','value':51}]}
def test_report_single_failed_check_is_visible_in_manifest_junit(tmp_path):
c=load();c.update(matrix='chromium',routes=[],journeys=[{'id':'flow','path':'/','steps':[step()]}])
c['devices']={'desktop':c['devices']['desktop']};c['capture']['repeats']=1
r=report('failed');r.update(run_id='unit',schema='testwins.report/v1',created='2026-09-22',project='p',tool_version='0.4.0',config_hash='a'*64,matrix='chromium',environment={},occurrences=[])
r=report('failed');r.update(run_id='unit',schema='testwins.report/v1',created='2026-09-22',project='p',tool_version='0.4.1',config_hash='a'*64,matrix='chromium',environment={},occurrences=[])
r['cells'][0].update(browser='chromium',device='desktop',version='stub',transport='cdp',errors=[],observed_scenes=1,expected_scenes=1)
finalize(tmp_path,r,c)
assert r['gate']['exit_code']==1 and r['cells'][0]['status']=='failed'
Expand Down Expand Up @@ -274,3 +274,15 @@ def test_packaged_profiles_validate_and_preserve_all_personas():
assert len(large['journeys'])==len(small['journeys'])==6
assert {j['id'] for j in large['journeys']}=={j['id'] for j in small['journeys']}
assert len(large['devices'])==2 and len(small['devices'])==1


def test_version_ssot_consistent():
import tomllib
import testwins
repo=Path(__file__).resolve().parents[1]
ver=(repo/'VERSION').read_text('utf-8').strip()
pyproj=tomllib.loads((repo/'pyproject.toml').read_text('utf-8'))['project']['version']
summary=json.loads((repo/'verification/summary.json').read_text('utf-8'))['version']
readme=(repo/'README.md').read_text('utf-8')
assert ver==pyproj==summary==testwins.__version__
assert f'# Testwins {ver}' in readme
2 changes: 1 addition & 1 deletion tools/release.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def package():
dist=ROOT/'dist';archive=dist/f'testwins-{VERSION}-final.zip'
artifacts=[dist/f'testwins-{VERSION}-py3-none-any.whl',dist/f'testwins-{VERSION}.tar.gz']
if not all(p.is_file() for p in artifacts):raise RuntimeError('Expected distributions not created')
excluded={'.git','.venv','.auth','.testwins','.pytest_cache','__pycache__','artifacts','baselines','build','dist',
excluded={'.git','.worktrees','.koru','.governance','.planfile','.subactor','.venv','.auth','.testwins','.pytest_cache','.ruff_cache','__pycache__','artifacts','baselines','build','dist',
'.testwins-live-secret','.testwins-integration-backup'}
selected=[]
for p in sorted(ROOT.rglob('*')):
Expand Down
2 changes: 1 addition & 1 deletion tools/standards.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def check(run: Path, upstream: Path, out: Path) -> dict:
spec=importlib.util.spec_from_file_location('testwins_trusted_upstream_logs',checker)
module=importlib.util.module_from_spec(spec);sys.modules[spec.name]=module;spec.loader.exec_module(module)
bundle,contract_sha=module.load_contract(upstream)
codes={p.stem for p in (ROOT/'errors').glob('*.md')}
codes={p.stem for p in (ROOT/'errors').glob('*.md') if p.name!='README.md'}
catalog=module.load_error_documents(ROOT,bundle,directory_relative='errors',declared=codes)
previous='0'*64;prior={};count=0
from jsonschema import Draft202012Validator,FormatChecker
Expand Down
2 changes: 1 addition & 1 deletion verification/summary.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"schema": "testwins.release-verification/v1",
"version": "0.4.0",
"version": "0.4.1",
"date": "2026-09-22",
"unit_and_local": {
"passed": 254,
Expand Down