api-native-theme-spec.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import { expect } from 'chai';
  2. import { nativeTheme, BrowserWindow, ipcMain } from 'electron/main';
  3. import { once } from 'node:events';
  4. import * as path from 'node:path';
  5. import { setTimeout } from 'node:timers/promises';
  6. import { closeAllWindows } from './lib/window-helpers';
  7. describe('nativeTheme module', () => {
  8. describe('nativeTheme.shouldUseDarkColors', () => {
  9. it('returns a boolean', () => {
  10. expect(nativeTheme.shouldUseDarkColors).to.be.a('boolean');
  11. });
  12. });
  13. describe('nativeTheme.themeSource', () => {
  14. afterEach(async () => {
  15. nativeTheme.themeSource = 'system';
  16. // Wait for any pending events to emit
  17. await setTimeout(20);
  18. closeAllWindows();
  19. });
  20. it('is system by default', () => {
  21. expect(nativeTheme.themeSource).to.equal('system');
  22. });
  23. it('should override the value of shouldUseDarkColors', () => {
  24. nativeTheme.themeSource = 'dark';
  25. expect(nativeTheme.shouldUseDarkColors).to.equal(true);
  26. nativeTheme.themeSource = 'light';
  27. expect(nativeTheme.shouldUseDarkColors).to.equal(false);
  28. });
  29. it('should emit the "updated" event when it is set and the resulting "shouldUseDarkColors" value changes', async () => {
  30. nativeTheme.themeSource = 'light';
  31. let updatedEmitted = once(nativeTheme, 'updated');
  32. nativeTheme.themeSource = 'dark';
  33. await updatedEmitted;
  34. updatedEmitted = once(nativeTheme, 'updated');
  35. nativeTheme.themeSource = 'light';
  36. await updatedEmitted;
  37. });
  38. it('should not emit the "updated" event when it is set and the resulting "shouldUseDarkColors" value is the same', async () => {
  39. nativeTheme.themeSource = 'dark';
  40. // Wait a few ticks to allow an async events to flush
  41. await setTimeout(20);
  42. let called = false;
  43. nativeTheme.once('updated', () => {
  44. called = true;
  45. });
  46. nativeTheme.themeSource = 'dark';
  47. // Wait a few ticks to allow an async events to flush
  48. await setTimeout(20);
  49. expect(called).to.equal(false);
  50. });
  51. const getPrefersColorSchemeIsDark = async (w: Electron.BrowserWindow) => {
  52. const isDark: boolean = await w.webContents.executeJavaScript(
  53. 'matchMedia("(prefers-color-scheme: dark)").matches'
  54. );
  55. return isDark;
  56. };
  57. it('should override the result of prefers-color-scheme CSS media query', async () => {
  58. const w = new BrowserWindow({ show: false, webPreferences: { contextIsolation: false, nodeIntegration: true } });
  59. await w.loadFile(path.resolve(__dirname, 'fixtures', 'blank.html'));
  60. await w.webContents.executeJavaScript(`
  61. window.matchMedia('(prefers-color-scheme: dark)')
  62. .addEventListener('change', () => require('electron').ipcRenderer.send('theme-change'))
  63. `);
  64. const originalSystemIsDark = await getPrefersColorSchemeIsDark(w);
  65. let changePromise = once(ipcMain, 'theme-change');
  66. nativeTheme.themeSource = 'dark';
  67. if (!originalSystemIsDark) await changePromise;
  68. expect(await getPrefersColorSchemeIsDark(w)).to.equal(true);
  69. changePromise = once(ipcMain, 'theme-change');
  70. nativeTheme.themeSource = 'light';
  71. await changePromise;
  72. expect(await getPrefersColorSchemeIsDark(w)).to.equal(false);
  73. changePromise = once(ipcMain, 'theme-change');
  74. nativeTheme.themeSource = 'system';
  75. if (originalSystemIsDark) await changePromise;
  76. expect(await getPrefersColorSchemeIsDark(w)).to.equal(originalSystemIsDark);
  77. w.close();
  78. });
  79. });
  80. describe('nativeTheme.shouldUseInvertedColorScheme', () => {
  81. it('returns a boolean', () => {
  82. expect(nativeTheme.shouldUseInvertedColorScheme).to.be.a('boolean');
  83. });
  84. });
  85. describe('nativeTheme.shouldUseHighContrastColors', () => {
  86. it('returns a boolean', () => {
  87. expect(nativeTheme.shouldUseHighContrastColors).to.be.a('boolean');
  88. });
  89. });
  90. describe('nativeTheme.inForcedColorsMode', () => {
  91. it('returns a boolean', () => {
  92. expect(nativeTheme.inForcedColorsMode).to.be.a('boolean');
  93. });
  94. });
  95. });