Chrono Mock
Ngôn ngữTiếng Việt

Làm giả ngày trong một ứng dụng Electron

Tìm kiếm điều này và mọi câu trả lời đều nói về việc sửa mã của chính bạn - mock đối tượng Date, dùng bộ hẹn giờ giả của framework kiểm thử. Không cái nào giúp được khi thứ bạn có là một ứng dụng đã dựng sẵn. Công cụ này chạy chính ứng dụng mà bạn đã có.

Vì sao việc chèn mã không đến được nó

Chế độ này tồn tại vì một thất bại cụ thể. Một bộ đếm Pomodoro xây trên Electron được chạy trong phiên x60 và phần đếm ngược của nó hoàn toàn không nhúc nhích. Việc tháo gói của ứng dụng ra cho thấy hai nguyên nhân độc lập, và không cái nào có cách khắc phục ở phía native:

  • Phần đếm ngược không đọc đồng hồ. Nó là một bộ đếm được tăng bởi setInterval, chạy bên trong một Web Worker. Không có lệnh gọi thời gian nào để chặn, vì ứng dụng chưa bao giờ hỏi mấy giờ.
  • Worker đó sống trong một tiến trình renderer bị cô lập, đúng nơi mà một thư viện được chèn từ bên ngoài không vào được.

Vì vậy cơ chế phía Windows không giúp được ở đây, và câu trả lời là nói chuyện với chính engine JavaScript của ứng dụng.

Thay vào đó điều gì xảy ra

Ứng dụng được khởi chạy với một cổng gỡ lỗi và một hồ sơ sạch dùng một lần, và các API thời gian của riêng nó được đặt lên đồng hồ của phiên qua giao thức DevTools - Date.now, hàm tạo new Date(), performance.now, setTimeout và setInterval.

Phần ghi đè được cài vào mọi ngữ cảnh mà ứng dụng mở ra, kể cả các Web Worker của nó - nơi bộ hẹn giờ thường hóa ra nằm, và là chỗ duy nhất mà việc chèn mã native chưa bao giờ có thể với tới.

Không có gì thay đổi về cách bạn điều khiển nó. Cùng một lệnh, cùng một cửa sổ, cùng bảng điều khiển phiên với hai đồng hồ và kết luận.

# Cùng lệnh như với ứng dụng native - chế độ được tự phát hiện
chrono run "%LOCALAPPDATA%\Programs\your-app\YourApp.exe" --at 2038-01-01T00:00:00 --mode x60

Hai giới hạn đáng biết trước khi bắt đầu

Việc khởi chạy mang tính xâm lấn, và cố ý nói to điều đó.

Ứng dụng được khởi động với cổng gỡ lỗi từ xa mở và một hồ sơ mới, cô lập trong %TEMP% - nó không chạy trên hồ sơ thật của bạn, và cũng không phải bản đã có sẵn trong khay hệ thống. Hồ sơ bị xóa khi phiên kết thúc, và nếu không xóa được, bản tóm tắt phiên sẽ nói ra thay vì lặng lẽ để lại.

Việc truyền vào --user-data-dir hoặc --remote-debugging-port của riêng bạn bị từ chối chứ không bị ghi đè, vì tai nạn dễ xảy ra nhất - trỏ phiên vào hồ sơ trình duyệt thật của bạn - không đáng để cho phép.

Các trang đọc múi giờ của phiên.

Mỗi trang và mỗi worker được đặt vào múi giờ của phiên, một độ lệch cố định không có giờ mùa hè, và kiểm tra độ lệch mà nó đọc, nên trang nào đọc múi giờ khác sẽ được báo cáo. Hai giới hạn: Intl gọi múi giờ đó bằng một độ lệch như GMT+02:00 chứ không phải tên thành phố, và tiến trình chính của ứng dụng Electron chạy JavaScript trong Node mà phiên không với tới, nên nó giữ đồng hồ thật - báo cáo có nói điều này.

Một điều nữa khiến người ta bất ngờ: một khoảng lặp đã được lên lịch giữ nguyên nhịp cũ khi bạn đổi tốc độ giữa phiên. Date.now, new Date() và performance.now phản ứng ngay, còn một setInterval đang chạy thì không, và phiên sẽ cảnh báo về điều đó thay vì để bạn kết luận rằng thay đổi chẳng làm gì cả.

Được kiểm thử tốt đến đâu

Thử nghiệm, và từ này có nghĩa xác định ở đây: nó hoạt động trên các mục tiêu mà nó được xây dựng để chống lại, chưa được kiểm thử rộng rãi, và kiểm toán tích hợp sẵn là nguồn chân lý của bạn chứ không phải trang này. Nó được xác minh thủ công, không phải bằng bộ kiểm thử tự động, trên một ứng dụng Electron thật chạy Windows 64-bit.

Độ bao phủ được báo cáo theo từng ngữ cảnh JavaScript thay vì theo tiến trình, vì đó là đơn vị tồn tại ở đây. Một ứng dụng đứng yên và không bao giờ hỏi giờ sẽ trung thực cho ra chưa xác định - nó không đọc đồng hồ, nên không thể khẳng định gì về việc nó có thấy đúng giờ hay không. Các kết luận có nghĩa là gì →

Dùng thử