AI 资讯
Link Manual Test Cases to Playwright and Robot Specs
Most teams already keep Playwright or Robot Framework specs next to the product. Manual cases often live somewhere else — a spreadsheet, a cloud TMS, or a wiki page nobody updates after the first release. That is why automation coverage is usually a quarterly guess: the catalog and the specs never share an id. Put both in the same Git repo , give every manual case a stable id, and linking becomes a text match. Any IDE agent can do that if the cases are files it can already see — no custom AI product inside a test tool. One repo, two layers of the same suite Manual cases are YAML files under .gitoza-lite/test/cases/ (VS Code / Cursor extension) or .gitoza/test/cases/ (Desktop app). The filename without .yaml is the case id . Automated tests live wherever your team already puts them — tests/ , e2e/ , robot/ — in the same repository. Traceability is a shared id: put that case id on the automation side as a tag (or name), and on the YAML side as automated: true plus a params pointer. A PR can change the case, the Playwright spec, and the link in one review. Step 1 — Draft manual cases in the IDE Open the repo in Cursor or VS Code. Point the agent at a few existing case files so it learns your title style, tags, and step length. Then feed it a user story, a ticket, or a screenshot. Ask for several cases at once, not one shallow step. A useful prompt looks like: Read .gitoza-lite/test/cases/shopflow/auth/ for format. From ticket SHOP-184, draft three YAML cases (happy path, invalid password, locked account). Filename = case id. Use tags auth and smoke where it fits. Save the files under the suite folder. Then open the Gitoza Lite Test Repository tab to browse, edit, and — when you are ready — run them as a manual suite with Pass / Fail / Skip. The extension does not ship its own model. It keeps cases as plain YAML so whatever assistant you already use can read and write them. A minimal case: --- title : Login with valid credentials priority : high tags : [ smoke , auth ]
AI 资讯
Preorders for Samsung’s new Z Fold and Flip 8 come with up to $350 in gift cards
Samsung's newest foldables are here. At Galaxy Unpacked, the company announced the Galaxy Z Flip 8, Galaxy Z Fold 8, and Galaxy Z Fold 8 Ultra. All three devices will be available on August 7th, but you can preorder them now starting at $1,199.99, $1,899.99, and $2,099.99, respectively. You probably noticed that Samsung's foldable lineup […]
AI 资讯
TRUE Coverage: How We Achieved 90% Faster CI by Measuring What Tests Actually Do
TL;DR: Use per-test coverage data to build a reverse map (file → tests that touch it). Git diff + map lookup = run only relevant tests. 43min → 4min CI time. The Problem Everyone Has Your test suite runs for 45 minutes. You change one file. Should you: Run all 2,000 tests? (Safe but slow) Run tests with matching filenames? (Fast but broken) Manually tag tests? (Gets stale immediately) We tried all three. They all failed. The Insight: Stop Guessing, Start Measuring What if we just measured what each test actually executes? Coverage tools have done this for years: { "src/MyComponent.js" : { "statements" : { "0" : 5 , "1" : 12 , "2" : 0 } } } Key insight: Coverage tools report per test run, not per test file. All we needed: save coverage after each individual test. The Architecture (5 Steps) Step 1: Instrument the Code // Build config (webpack/vite/rollup/etc) export default { plugins : [ process . env . COLLECT_COVERAGE && coveragePlugin ({ include : ' src/**/* ' , exclude : [ ' **/*.test.* ' ] }) ] } Works with: Istanbul (JS), coverage.py (Python), SimpleCov (Ruby), JaCoCo (Java) Step 2: Collect Coverage Per Test // Test framework afterEach hook afterEach ( async () => { const coverage = getCoverageData (); saveCoverage ( `coverage- ${ testName } .json` , coverage ); }); Step 3: Build the Reverse Map const map = {} ; for (const coverageFile of allCoverageFiles()) { const testName = extractTestName(coverageFile); const coverage = JSON.parse(read(coverageFile)); map [ testName ] = [] ; for (const [ sourceFile , data ] of Object.entries(coverage)) { if (wasExecuted(data)) { map [ testName ] .push(sourceFile); } } } Example output: { "tests/user-profile.test.js" : [ "src/components/Profile.jsx" , "src/components/Card.jsx" , "src/utils/formatters.js" ] } The magic: The test told us what it executed. No parsing, no guessing. Step 4: Detect Tests CHANGED = $( git diff origin/main...HEAD --name-only ) TESTS = $( lookupTestsInMap " $CHANGED " ) npm test $TESTS Step 5: Auto-Up
AI 资讯
Catch the dangerous Postgres migration at the CI step
-- looks routine in review, locks your table in production: CREATE INDEX idx_orders_customer ON orders ( customer_id ); ALTER TABLE users ALTER COLUMN email SET NOT NULL ; Both of those statements hold a lock that blocks traffic while they scan or build against the table. On a small table you never notice. On a busy production table it is downtime, and a diff review does not catch it because the SQL looks fine. pg-migration-guard is a free tool that reads the migration and flags these before they reach production: $ pg-migration-guard V42__orders.sql WARN IDX01 CREATE INDEX without CONCURRENTLY [becomes a blocker on a large or busy table] Why: Plain CREATE INDEX takes a lock that blocks all writes until the build finishes. Safe: CREATE INDEX CONCURRENTLY idx ON tbl (col); -- outside a transaction WARN NN01 SET NOT NULL scans the whole table under ACCESS EXCLUSIVE Safe: ADD CONSTRAINT c CHECK (col IS NOT NULL) NOT VALID; VALIDATE CONSTRAINT c; then SET NOT NULL; Summary: 0 blocker, 2 warn, 0 advisory Why migrations bite Whether a Postgres migration is safe has almost nothing to do with intent and everything to do with locks. A migration is dangerous when it holds a strong lock while it scans or rewrites a large table. ACCESS EXCLUSIVE blocks reads and writes; SHARE blocks writes. The change that reads fine in review is the one that quietly takes that lock. Put it in CI The most useful place for this is the pull request, so a risky migration fails the build before anyone merges it. There is a GitHub Action: name : migration-guard on : pull_request : paths : [ " db/migration/**.sql" ] jobs : guard : runs-on : ubuntu-latest steps : - uses : actions/checkout@v4 - uses : actions/setup-python@v5 with : python-version : " 3.x" - uses : technical-turtle/pg-migration-guard@v1 with : path : db/migration fail-on : blocker Each finding shows up as an inline annotation on the diff, so the author sees exactly which line is the problem and what the safe rewrite is. Or run it locall
AI 资讯
The Friction Is A Feature, Not A Bug: Teaching and Mentoring in the Age of AI
Those who have been following me for a while will know that teaching and mentoring are a Big Deal™️ to me. Before I got into tech I was a teacher, and still consider myself a teacher at heart. Being a teacher and mentor was never separate in my eyes from being a good programmer and engineer; on the contrary, teaching was a tool that helped me become better at my craft at every stage of the journey. But in the last few years, and accelerating in the last few months, the landscape for teaching and learning has been changing at a scary pace. The advent of LLMs and "AI" coding assistants has drastically shifted how we acquire engineering skills in ways that we are definitely not prepared for. All of that has prompted many thoughts and conversations, and I hope to distill some of them in this blog post. In true Talmudic fashion, this post doesn't contain too many answers and will hopefully leave you with more questions than you started with. But asking the questions is how we start these conversations, and these conversations need to be happening if we are to do right by the coming generation of programmers and engineers. Don't Spoon-Feed Me As a student, whether in Yeshiva when I used to spend hours each day poring over dense Talmudic legal debates and esoteric Chassidic philosophy or later while learning Rails and React at the Flatiron bootcamp, I quickly realized an uncomfortable truth about skill acquisition. My best, most profound learning never happened when a lesson went smoothly; it happened when I was painfully stuck, banging my head against a cryptic error message or wrestling with a concept that just wouldn't click (usually at 2 AM, fueled by cold coffee and sheer stubbornness). When you strip away that struggle, you get rid of the growth. And when you get rid of the growth, the learning just doesn't happen. Even if you memorize just enough to pass the test, "easy come easy go." Without that cognitive friction, the knowledge evaporates the moment you close you
开发者
WebP vs AVIF vs PNG vs JPEG: A Practical Format Guide for 2026
After spending 2 years building an image compression tool, here's my no-nonsense format guide. ## The Rule | If it's... | Use... | |---|---| | Logo, icon, screenshot | PNG | | Photo, everyday image | WebP | | Smallest possible file | AVIF | | Maximum compatibility | JPEG | ## Why? PNG — Lossless. Keeps text and sharp edges crisp. Supports transparency. But files are large for photos. JPEG — Works literally everywhere since 1992. Good compression for photos. No transparency support. At 80-85% quality, the visual difference from 100% is invisible but the file is half the size. WebP — The sweet spot. 25-35% smaller than JPEG with same quality. Supports both lossy and lossless. Supports transparency. Every modern browser supports it now (97%+ global coverage). For most websites, this is the right answer. AVIF — The next-gen format. 50% smaller than JPEG, 30% smaller than WebP. Supports HDR, 12-bit color, and both lossy/lossless. The catch: not supported on older devices (iOS 15 and below). Use it with a <picture> fallback. ## Real Numbers I ran the same photo through all four formats at comparable quality: JPEG (90%): 842 KB PNG: 3,241 KB WebP (90%): 547 KB AVIF (90%): 382 KB WebP cut the JPEG size by 35%. AVIF cut it by 55%. ## What I Recommend I built CompressFast ( https://compressfast.site ) — a free browser-based image compressor that handles all these formats. No uploads, no servers, everything runs locally.
AI 资讯
#02 – Encapsulation & Abstraction in Python
Welcome to Day 2! Today we focus on two core pillars of Object-Oriented Programming: Encapsulation: Hiding internal state and requiring all interaction to go through performing validation or controlled methods. Abstraction: Hiding complex implementation details and exposing only a clean, simplified interface to the user. 1. Access Modifiers: Public, Protected, & Private 🛡️ Python does not have strict enforcement keywords like public or private found in Java or C++. Instead, it uses naming conventions and name mangling to communicate intent and protect internal data. ┌─────────────────────────────────────────────────────────────────────────────┐ │ ACCESS MODIFIERS IN PYTHON │ ├──────────────┬───────────────┬──────────────────────────────────────────────┤ │ Level │ Syntax │ Scope / Intended Access │ ├──────────────┼───────────────┼──────────────────────────────────────────────┤ │ Public │ self.name │ Accessible anywhere (inside & outside class) │ │ Protected │ self._balance │ Internal & subclasses only (Convention) │ │ Private │ self.__pin │ Class internal only (Triggers Name Mangling) │ └──────────────┴───────────────┴──────────────────────────────────────────────┘ Public ( self.name ): Fully accessible from anywhere. Protected ( self._balance ): Single leading underscore. Signals to developers: "This is internal—do not mutate or access outside this class or its subclasses." Private ( self.__pin ): Double leading underscore. Triggers name mangling ( _ClassName__attribute ), making it hard to accidentally access or override outside the class. 💻 Code Example: Access Modifiers & Name Mangling class SecureVault : def __init__ ( self , owner : str , balance : float , pin_code : str ): self . owner = owner # Public self . _balance = balance # Protected (convention) self . __pin = pin_code # Private (name mangled) def verify_pin ( self , pin : str ) -> bool : return self . __pin == pin vault = SecureVault ( " Alice " , 50000.0 , " 9876 " ) # Public access works as expected
AI 资讯
Surround sound speaker channel numbers explained: Bigger isn't always better
Here's what to pay attention to when building a home theater system.
AI 资讯
If you pay a hacker’s ransom, chances are that they’ll come back for more
The long-held understanding among security researchers and network defenders is that it's impossible to negotiate in good faith with an extortion racket because there's no incentive for the other side to actually walk away.
AI 资讯
Stop Screenshotting Architecture Diagrams: Build Them as Single-File HTML
TL;DR Spent today rebuilding two training diagrams — a layered reference architecture and a workflow swimlane — as single-file HTML instead of exported images. The trick: data in a plain JS array, layout in CSS Grid, connectors in an SVG overlay measured at runtime . Result: diagrams you can step through, click into, and hand over as one file that opens offline. Why not just export a PNG? Because a screenshot is stale by the next sprint, and nobody re-opens the drawing tool to fix it. Approach Editable by a dev Interactive Portable PNG from a drawing tool No (need the source file) No Yes Mermaid in a doc Yes No Needs a renderer Hand-built HTML Yes (it's a data array) Yes One file, opens anywhere The third option costs a few hours once. After that, updating a component is editing one object in an array. Separate the data from the drawing This is the whole design. Nothing about position, colour, or DOM lives in the content: const TIERS = [ { key : ' clients ' , label : ' Clients ' , sub : ' consumers · admins ' }, { key : ' edge ' , label : ' Edge ' , sub : ' TLS · load balancing ' }, // ... ]; const COMPONENTS = [ { id : ' app ' , tier : ' app ' , x : . 34 , label : ' Control Plane ' , tech : ' PHP-FPM ' , role : ' Governance UI and sync orchestration. ' , points : [{ type : ' info ' , text : ' Pushes approved config downstream ' }] }, // ... ]; const LINKS = [[ ' consumers ' , ' edge ' ], [ ' edge ' , ' gateway ' ], /* ... */ ]; tier picks the row. x is a fraction (0..1) across that row , not a pixel. So the layout survives any viewport without me hand-tuning coordinates. Layout: Grid for the boxes, SVG on top for the wires +--------------------------------------------------+ | lane label | [card 1] [card 2] [card 3] | <- CSS Grid row |------------+-------------------------------------| | lane label | [card 4] [card 5] | +--------------------------------------------------+ ^ ^ sticky column SVG overlay (position:absolute; inset:0) draws paths between measured centre
产品设计
Vizhi
Mission control for Codex CLI on a Logitech MX keypad Discussion | Link
AI 资讯
Philips’ new smart toothbrush shows you where you didn’t properly brush
The latest addition to Philips' Sonicare line of smart electric toothbrushes could take the guesswork out of your brushing routine. The Next-Generation DiamondClean 9900 Prestige uses a third-generation AI model to provide real-time feedback on how you're brushing through a glowing ring on its base, while a touchscreen highlights areas of your mouth that may […]
AI 资讯
Microsoft is bringing original Xbox games to PC
Microsoft is expanding its Xbox backward compatibility efforts today by bringing original Xbox games to PC. An early preview release will see four classic Xbox games available on PC today, as part of a bigger effort to bring more Xbox console games to PC in the future. The first four games are Blinx: The Time […]
AI 资讯
AMD commits up to $5 billion to Anthropic
AMD says it's going to invest up to $5 billion in Anthropic, while helping to expand the AI company's computing power, according to an announcement on Wednesday. As part of the new partnership, Anthropic will deploy up to 2 gigawatts of AMD's Instinct MI450 AI GPUs using the chipmaker's new Helios rack-scale system, as reported […]
AI 资讯
SwiftScale Software
QA agent that tests apps the way you'd explain them Discussion | Link
科技前沿
What happens when you try to chop a photon in half?
A mirror that moves mid-photon could release a shower of new photons.
开源项目
GitHub Increased Instant Navigation from 4% to 22% by Rethinking Client Side Architecture
GitHub redesigned GitHub Issues navigation using a client-side architecture that combines caching, predictive prefetching, and service workers to reduce perceived latency. The approach uses IndexedDB, in-memory caching, and background synchronization to serve data faster. GitHub reported instant navigation improvements from 4% to 22%, with latency reductions across multiple navigation By Leela Kumili
AI 资讯
Loop Engineering: How to Stop Your Agent Reward-Hacking Its Own Checks
You gave the agent a failing test and told it to get the suite green. It came back green. Then you...
科技前沿
Samsung Galaxy Z Flip 8 vs. Motorola Razr Ultra: Which is the better buy?
How to choose between two of the most notable flip phones on the market.
AI 资讯
Samsung unveils new Galaxy Z8 foldables and Galaxy Watches, available August 7
Samsung's new foldables are slimmer, faster, and more expensive.