datagrok-tools 6.7.9 → 6.7.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,6 +16,7 @@ exports.getToken = getToken;
16
16
  exports.getWebUrl = getWebUrl;
17
17
  exports.getWebUrlFromPage = getWebUrlFromPage;
18
18
  exports.isPackageOnServer = isPackageOnServer;
19
+ exports.isPackageU2Usage = isPackageU2Usage;
19
20
  exports.loadPackage = loadPackage;
20
21
  exports.loadPackages = loadPackages;
21
22
  exports.loadTestsList = loadTestsList;
@@ -159,6 +160,36 @@ function getDevKey(hostKey) {
159
160
  key
160
161
  };
161
162
  }
163
+ const U2_USAGE = 'u2 usage:';
164
+ /** The u2 usage mode a package built on u2 or ems is tested in: a misuse throws, unless `U2_STRICT` says otherwise
165
+ * (`report` logs each one as a `u2 usage:` line and the run does not fail on them). */
166
+ const U2_MODE = process.env.U2_STRICT ?? 'throw';
167
+
168
+ /** Whether a `u2 usage:` line the page logged fails the run: the package is tested with u2 strict. */
169
+ function failsOnU2Usage() {
170
+ return U2_MODE !== 'report' && usesU2(process.cwd());
171
+ }
172
+
173
+ /** Whether a `u2 usage:` line is the tested package's: a stack frame it carries is in the package's bundle
174
+ * (`…/files/<package>/…`), or it carries none to tell. A line whose frames are all in other bundles is another
175
+ * package's misuse, reported but not failed on. */
176
+ function isPackageU2Usage(line, packageName) {
177
+ const frames = line.match(/https?:\/\/[^\s()]+/g) ?? [];
178
+ const bundle = `/files/${packageName?.toLowerCase()}/`;
179
+ return packageName === undefined || frames.length === 0 || frames.some(f => f.toLowerCase().includes(bundle));
180
+ }
181
+ function usesU2(packageDir) {
182
+ try {
183
+ const json = JSON.parse(_fs.default.readFileSync(_path.default.join(packageDir, 'package.json'), 'utf-8'));
184
+ const deps = {
185
+ ...json.dependencies,
186
+ ...json.devDependencies
187
+ };
188
+ return '@datagrok-libraries/u2' in deps || '@datagrok-libraries/ems' in deps;
189
+ } catch {
190
+ return false;
191
+ }
192
+ }
162
193
  function appendUrlParams(url, extraParams) {
163
194
  if (!extraParams) return url;
164
195
  return url + (url.includes('?') ? '&' : '?') + extraParams;
@@ -194,6 +225,9 @@ async function getBrowserPage(puppeteer, params = defaultLaunchParameters, urlPa
194
225
  height: 1080
195
226
  });
196
227
  page.setDefaultNavigationTimeout(0);
228
+ if (usesU2(process.cwd())) await page.evaluateOnNewDocument(mode => {
229
+ globalThis.__U2_STRICT__ = mode;
230
+ }, U2_MODE);
197
231
  await page.goto(`${url}/oauth/`);
198
232
  await page.browser().setCookie({
199
233
  name: 'auth',
@@ -537,6 +571,16 @@ function printBrowsersResult(browserResult, verbose = false) {
537
571
  console.log('Skipped tests: ' + (browserResult?.skippedAmount ?? 0));
538
572
  console.log('Failed tests: ' + (browserResult?.failedAmount ?? 0));
539
573
  }
574
+ const own = browserResult.u2Usage?.filter(l => isPackageU2Usage(l, process.env.TARGET_PACKAGE)) ?? [];
575
+ const others = browserResult.u2Usage?.filter(l => !own.includes(l)) ?? [];
576
+ if (own.length) {
577
+ color.warn(failsOnU2Usage() ? `${own.length} u2 usage error(s) caught on the page (the run fails):` : `${own.length} u2 usage report(s), in report mode (the run does not fail on them):`);
578
+ for (const line of own) color.warn(` ${line}`);
579
+ }
580
+ if (others.length) {
581
+ color.warn(`${others.length} u2 usage line(s) from other packages' code (the run does not fail on them):`);
582
+ for (const line of others) color.warn(` ${line}`);
583
+ }
540
584
  if (browserResult.failed) {
541
585
  if (browserResult.verboseFailed === 'Package not found') color.fail('Tests not found');else color.fail('Tests failed.');
542
586
  } else color.success('Tests passed.');
@@ -860,6 +904,11 @@ async function runBrowser(testExecutionData, browserOptions, browsersId, testInv
860
904
  // Subscribe to page console events for modern output formatting
861
905
  // On retry, old listeners were removed so we need to re-attach
862
906
  page.on('console', msg => reporter.onLine(msg.text()));
907
+ const u2Usage = [];
908
+ page.on('console', msg => {
909
+ const text = msg.text();
910
+ if (text.includes(U2_USAGE) && !u2Usage.includes(text)) u2Usage.push(text);
911
+ });
863
912
  const testingResults = await page.evaluate((testData, options) => {
864
913
  if (options.benchmark) window.DG.Test.isInBenchmark = true;
865
914
  if (options.reproduce) window.DG.Test.isReproducing = true;
@@ -918,12 +967,14 @@ async function runBrowser(testExecutionData, browserOptions, browsersId, testInv
918
967
  // Return browser session for potential reuse
919
968
  return {
920
969
  ...testingResults,
970
+ failed: testingResults.failed || failsOnU2Usage() && u2Usage.some(l => isPackageU2Usage(l, process.env.TARGET_PACKAGE)),
921
971
  browserSession: browserOptions.keepBrowserOpen ? {
922
972
  browser,
923
973
  page,
924
974
  webUrl
925
975
  } : undefined,
926
- modernOutput: reporter.modernOutput
976
+ modernOutput: reporter.modernOutput,
977
+ u2Usage
927
978
  };
928
979
  }, testInvocationTimeout);
929
980
  }
@@ -938,7 +989,8 @@ async function mergeBrowsersResults(browsersResults) {
938
989
  failedAmount: browsersResults[0].failedAmount,
939
990
  csv: browsersResults[0].csv,
940
991
  error: '',
941
- modernOutput: browsersResults.some(r => r.modernOutput)
992
+ modernOutput: browsersResults.some(r => r.modernOutput),
993
+ u2Usage: [...new Set(browsersResults.flatMap(r => r.u2Usage ?? []))]
942
994
  };
943
995
  for (const browsersResult of browsersResults) {
944
996
  if (mergedResult.csv === browsersResult.csv) continue;
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "type": "git",
5
5
  "url": "https://github.com/datagrok-ai/public.git"
6
6
  },
7
- "version": "6.7.9",
7
+ "version": "6.7.10",
8
8
  "description": "Utility to upload and publish packages to Datagrok",
9
9
  "homepage": "https://github.com/datagrok-ai/public/tree/master/tools#readme",
10
10
  "engines": {
@@ -202,8 +202,8 @@ class FuncGeneratorPlugin {
202
202
  this._checkPackageFileForDecoratorsExport(packageFilePath);
203
203
  // Uncommment to add obvious import/export
204
204
  // this._writeToPackageFile(packageFilePath, genImports, genExports);
205
+ api({_: ['api']});
205
206
  });
206
- api({_: ['api']});
207
207
  }
208
208
 
209
209
  _addNodeData(
package/vitest.config.mts CHANGED
@@ -1,9 +1,12 @@
1
1
  import {defineConfig} from 'vitest/config';
2
2
 
3
3
  export default defineConfig({
4
+ // Babel writes each .js beside its .ts in bin/: tests must load the sources, and one copy of each module.
5
+ resolve: {extensions: ['.ts', '.mts', '.mjs', '.js', '.jsx', '.tsx', '.json']},
4
6
  test: {
5
7
  projects: [
6
8
  {
9
+ extends: true,
7
10
  test: {
8
11
  name: 'unit',
9
12
  environment: 'node',
@@ -12,6 +15,7 @@ export default defineConfig({
12
15
  },
13
16
  },
14
17
  {
18
+ extends: true,
15
19
  test: {
16
20
  name: 'integration',
17
21
  environment: 'node',