api-native-theme-spec.ts 4.8 KB

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